Robolectric can't find resource or manifest file

lukjar picture lukjar · Sep 10, 2013 · Viewed 14.2k times · Source

I've created a new TestProject and added following line to my testMethod:

Robolectric.getShadowApplication().getString(R.string.mystring);

My test failed with

android.content.res.Resources$NotFoundException: unknown resource 2131558482

The console displays the following warnings:

WARNING: No manifest file found at .\..\..\MyProject\AndroidManifest.xml.Falling back to the Android OS resources only.
To remove this warning, annotate your test class with @Config(manifest=Config.NONE).
WARNING: no system properties value for ro.build.date.utc

Is AndroidManifest.xml necessary to get string resources? I tried to add Manifest by org.robolectric.Config.properties and @Config but the warning still occurs and I can't get string resource. I made sure the relative path to manifest is correct. I also tried changing the JUnit run configuration but this did not help.

Answer

user3635764 picture user3635764 · May 14, 2014

Solution to the problem described here: http://blog.futurice.com/android_unit_testing_in_ides_and_ci_environments

The Missing Manifest

You should have noticed by now that Robolectric complains about not being able to find your Android Manifest. We’ll fix that by writing a custom test runner. Add the following as app/src/test/java/com/example/app/test/RobolectricGradleTestRunner.java:

package com.example.app.test;

import org.junit.runners.model.InitializationError;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.res.Fs;

public class RobolectricGradleTestRunner extends RobolectricTestRunner {
  public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError {
    super(testClass);
  }

  @Override
  protected AndroidManifest getAppManifest(Config config) {
    String myAppPath = RobolectricGradleTestRunner.class.getProtectionDomain()
                                                        .getCodeSource()
                                                        .getLocation()
                                                        .getPath();
    String manifestPath = myAppPath + "../../../src/main/AndroidManifest.xml";
    String resPath = myAppPath + "../../../src/main/res";
    String assetPath = myAppPath + "../../../src/main/assets";
    return createAppManifest(Fs.fileFromPath(manifestPath), Fs.fileFromPath(resPath), Fs.fileFromPath(assetPath));
  }
}

Remember to change the RunWith annotation in the test class.