Robolectric: Resources$NotFoundException: 带有 Android Gradle 插件 3 的字符串资源 ID
Robolectric: Resources$NotFoundException: String resource ID with Android Gradle Plugin 3
Android Studio 3.0 Beta2
classpath 'com.android.tools.build:gradle:3.0.0-beta3'
testCompile 'org.robolectric:robolectric:3.4.2'
我正在使用的测试 class 无法 运行:
@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()));
}
}
这是错误的堆栈跟踪:
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)
在 Edit Configurations
中,我已将 Working Directory
设置为 $MODULE_DIR$
非常感谢任何建议。
As mentioned by an engineer from Google team (most possibly Xavier Ducrohet), Robolectric 与 AAPT2 有问题:
Robolectric is not compatible with aapt2.
这里有两个选项。
第一个选项 - 按照 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 {
}
第二个选项:禁用 AAPT2 在 gradle.properties
文件中添加以下行:
android.enableAapt2=false
如果您的构建由于 AAPT2
资源处理问题而失败,或者您想使用 Roboelectric
,您可以通过在 gradle.properties
[= 中设置 android.enableAapt2=false
来禁用 AAPT2
28=] 文件并通过 运行 ./gradlew --stop
从命令行重新启动 Gradle 守护进程。
Robolectric documentation 声明以下配置应与 Android Studio 3.x 一起使用:
android {
testOptions {
unitTests.includeAndroidResources true
}
}
就我而言,以下解决了我的问题:
“问题与 android 工作室有关。转到 'Run' -> 'Edit configurations...' 并将 'Working directory' 值更改为
$MODULE_DIR$
运行 你的测试。
更多信息在 'Building with Android Studio' 下。
如果您不能简单地包含资源,您也可以尝试 @Config(manifest = "<projectFolder>/src/main/AndroidManifest.xml")
,因为某些项目测试会因包含资源而失败。
(对于可能正在寻找类似问题解决方案的任何人)
一定要用
RuntimeEnvironment.application
和不是:
RuntimeEnvironment.systemContext
当您尝试解析资源时 "manually"。
这是 Resources$NotFoundException
可能与 Robolectric
一起出现的一种情况。
我使用的是浓缩咖啡,为此你需要使用应用程序资源,而不是测试资源。
所以不用
InstrumentationRegistry.getInstrumentation().context.resources.getString("key")
我用过
activityRule.activity.getString("key")
不是问题的直接答案,但如果您正在测试需要上下文来查询资源的内容,我发现以下方法工作得很好:
ApplicationProvider.getApplicationContext()
(或 RuntimeEnvironment.application - 但不赞成使用上述内容)
Android Studio 3.0 Beta2
classpath 'com.android.tools.build:gradle:3.0.0-beta3'
testCompile 'org.robolectric:robolectric:3.4.2'
我正在使用的测试 class 无法 运行:
@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()));
}
}
这是错误的堆栈跟踪:
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)
在 Edit Configurations
中,我已将 Working Directory
设置为 $MODULE_DIR$
非常感谢任何建议。
As mentioned by an engineer from Google team (most possibly Xavier Ducrohet), Robolectric 与 AAPT2 有问题:
Robolectric is not compatible with aapt2.
这里有两个选项。
第一个选项 - 按照 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 {
}
第二个选项:禁用 AAPT2 在 gradle.properties
文件中添加以下行:
android.enableAapt2=false
如果您的构建由于 AAPT2
资源处理问题而失败,或者您想使用 Roboelectric
,您可以通过在 gradle.properties
[= 中设置 android.enableAapt2=false
来禁用 AAPT2
28=] 文件并通过 运行 ./gradlew --stop
从命令行重新启动 Gradle 守护进程。
Robolectric documentation 声明以下配置应与 Android Studio 3.x 一起使用:
android {
testOptions {
unitTests.includeAndroidResources true
}
}
就我而言,以下解决了我的问题: “问题与 android 工作室有关。转到 'Run' -> 'Edit configurations...' 并将 'Working directory' 值更改为 $MODULE_DIR$
运行 你的测试。
更多信息在 'Building with Android Studio' 下。
如果您不能简单地包含资源,您也可以尝试 @Config(manifest = "<projectFolder>/src/main/AndroidManifest.xml")
,因为某些项目测试会因包含资源而失败。
(对于可能正在寻找类似问题解决方案的任何人)
一定要用
RuntimeEnvironment.application
和不是:
RuntimeEnvironment.systemContext
当您尝试解析资源时 "manually"。
这是 Resources$NotFoundException
可能与 Robolectric
一起出现的一种情况。
我使用的是浓缩咖啡,为此你需要使用应用程序资源,而不是测试资源。
所以不用
InstrumentationRegistry.getInstrumentation().context.resources.getString("key")
我用过
activityRule.activity.getString("key")
不是问题的直接答案,但如果您正在测试需要上下文来查询资源的内容,我发现以下方法工作得很好:
ApplicationProvider.getApplicationContext()
(或 RuntimeEnvironment.application - 但不赞成使用上述内容)