Robolectric: Resources$NotFoundException: String resource ID with Android Gradle Plugin 3

14,966

Solution 1

As mentioned by an engineer from Google team (most possibly Xavier Ducrohet), Robolectric has issues with AAPT2:

Robolectric is not compatible with aapt2.

Two options here.

First option - follow Robolectric guidelines for Android Studio 3.0+

Add the following to your build.gradle:

android {
  testOptions {
    unitTests {
      includeAndroidResources = true
    }
  }
}

Annotate your test with the Robolectric test runner:

@RunWith(RobolectricTestRunner.class)
public class SandwichTest {
}

Second option: disable AAPT2 adding following line into gradle.properties file:

android.enableAapt2=false

Solution 2

The Robolectric documentation states that the following configuration should be used with Android Studio 3.x:

android {
  testOptions {
    unitTests.includeAndroidResources true
  }
}

Solution 3

(for anyone that might be looking for a solution to a similar problem)


Be sure to use

RuntimeEnvironment.application

and not:

RuntimeEnvironment.systemContext

when you're trying to resolve resources "manually".

That's one case in which Resources$NotFoundException might show up with Robolectric.

Solution 4

Not a direct answer to the question, but if you are testing something that needs a context to query resources against I have found the following to work quite well:

ApplicationProvider.getApplicationContext()

(or RuntimeEnvironment.application -- but this is deprecated in favor of the above)

Solution 5

If your build fails due to an AAPT2 resource processing issue or you want to use Roboelectric, you can disable AAPT2 by setting android.enableAapt2=false in your gradle.properties file and restarting the Gradle daemon by running ./gradlew --stop from the command line.

Official guideline Android Studio 3.0 Release

Share:
14,966
ant2009
Author by

ant2009

Updated on June 06, 2022

Comments

  • ant2009
    ant2009 about 2 years
    Android Studio 3.0 Beta2
    classpath 'com.android.tools.build:gradle:3.0.0-beta3'
    testCompile 'org.robolectric:robolectric:3.4.2'
    

    Test class that I am using that fails to run:

    @Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
    @RunWith(RobolectricTestRunner.class)
    public class RecipeAdapterTest {
        private MainActivity activity;
    
        @Before
        public void setup() {
    
        activity = Robolectric.setupActivity(MainActivity.class);
    
        /* Also tried this same Error
         activity = Robolectric.buildActivity(MainActivity)
                    .create()
                    .resume()
                    .get();
        */
        }
    
        @Test
        public void testActivityShouldNotBeNull() {
            assertThat(activity, is(notNullValue()));
        }
    }
    

    This is the stack trace of the error:

    android.content.res.Resources$NotFoundException: String resource ID #0x7f0c0020
    
        at android.content.res.Resources.getText(Resources.java:274)
        at android.content.res.Resources.getString(Resources.java:360)
        at android.content.Context.getString(Context.java:376)
        at org.robolectric.shadows.ShadowActivity.getActivityTitle(ShadowActivity.java:100)
        at org.robolectric.shadows.ShadowActivity.callAttach(ShadowActivity.java:110)
        at org.robolectric.android.controller.ActivityController.attach(ActivityController.java:56)
        at org.robolectric.android.controller.ActivityController.of(ActivityController.java:25)
        at org.robolectric.Robolectric.buildActivity(Robolectric.java:98)
        at org.robolectric.Robolectric.buildActivity(Robolectric.java:94)
        at org.robolectric.Robolectric.setupActivity(Robolectric.java:102)
        at me.androidbox.busbybaking.adapters.RecipeAdapterTest.setup(RecipeAdapterTest.java:63)
    

    In the Edit Configurations I have set the Working Directory to $MODULE_DIR$

    Many thanks for any suggestion.

  • ant2009
    ant2009 almost 7 years
    Thanks, it looks like android.enableAapt2=false does the trick.
  • Morozov
    Morozov over 5 years
    This works, but disabling this option: android.enableAapt2=false caused other errors. Now we have to add a parameter for string resources. Maybe there is some better solution?
  • Ajay Vishwakarma
    Ajay Vishwakarma about 3 years
    android.enableAapt2=false is deprecated now