Android Studio - Robolectric: android.content.res.Resources$NotFoundException: 没有这样的标签 com.my.app:string/app_name
Android Studio - Robolectric: android.content.res.Resources$NotFoundException: no such label com.my.app:string/app_name
这个问题我似乎无法解决,我已经阅读了大约 3 或 4 多篇文章和主题以试图解决它。我在下面概述了所有内容。
基本上问题是,我的 Robolectric 有问题吗?还是我遗漏了一些小步骤,或者我有一个奇怪的插件组合。对此的任何指导将不胜感激。
Windows 7
版本:
- Gradle 2.7
- Android Studio 1.3.2
- Robolectric 3.0
- Roboguice 3.+
项目依赖项:
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
classpath "com.newrelic.agent.android:agent-gradle-plugin:4.244.0"
classpath 'com.github.triplet.gradle:play-publisher:1.1.2'
classpath 'org.moallemi.gradle.advanced-build-version:gradle-plugin:1.5.0'
}
应用依赖项
import org.moallemi.gradle.internal.VersionCodeType
apply plugin: 'com.android.application'
apply plugin: 'newrelic'
apply plugin: 'com.github.triplet.play'
apply plugin: 'org.moallemi.advanced-build-version'
android {
def SERVICE_ACCOUNT = “account”;
def P12_KEY = file('mykey.p12')
signingConfigs {
releaseConfig {
…
}
}
compileSdkVersion 22
buildToolsVersion '22.0.1'
advancedVersioning {
nameOptions {
versionMajor 6
versionMinor advancedVersioning.versionCode
}
codeOptions {
versionCodeType VersionCodeType.AUTO_INCREMENT_ONE_STEP
}
}
defaultConfig {
applicationId "com.my.app ="
minSdkVersion 15
targetSdkVersion 22
versionCode = advancedVersioning.versionCode
versionName = advancedVersioning.versionName
}
buildTypes {
def STRING = "String"
def URL = "URL"
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.releaseConfig
}
staging {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
development {
minifyEnabled false
}
debug {
minifyEnabled false
}
}
testOptions {
unitTests.returnDefaultValues = true
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.android.gms:play-services:4.2.+'
compile(name: 'library-release', ext: 'aar')
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.google.code.gson:gson:2.3.1'
compile 'org.roboguice:roboguice:3.+'
provided 'org.roboguice:roboblender:3.+'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile "org.robolectric:robolectric:3.0"
}
repositories {
flatDir {
dirs 'libs'
}
}
自定义Gradle亚军
public class M1stRoboelectricGradleTestRunner extends RobolectricTestRunner {
public M1stRoboelectricGradleTestRunner(Class<?> testClass) throws InitializationError {
super(testClass);
String buildVariant = (BuildConfig.FLAVOR.isEmpty()
? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE;
String intermediatesPath = BuildConfig.class.getResource("")
.toString().replace("file:", "");
intermediatesPath = intermediatesPath
.substring(0, intermediatesPath.indexOf("/classes"));
System.setProperty("android.package",
BuildConfig.APPLICATION_ID);
System.setProperty("android.manifest",
intermediatesPath + "/manifests/full/"
+ buildVariant + "/AndroidManifest.xml");
System.setProperty("android.resources",
intermediatesPath + "/res/merged/" + buildVariant);
System.setProperty("android.assets",
intermediatesPath + "/assets/" + buildVariant);
}
@Override protected AndroidManifest getAppManifest(Config config) {
String manifestProperty = System.getProperty("android.manifest");
String resProperty = System.getProperty("android.resources");
String assetsProperty = System.getProperty("android.assets");
AndroidManifest manifest = new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
Fs.fileFromPath(assetsProperty)){
};
manifest.setPackageName("com.my.app");
return manifest;
}
}
测试Class
@RunWith(M1stRoboelectricGradleTestRunner.class)
public class MainActivityTest {
private MainActivity mActivity;
private Button mButton;
private TextView mTextView;
@Before
public void setup() {
mActivity = Robolectric.buildActivity(
MainActivity.class).create().get();
mButton = (Button) mActivity.findViewById(R.id.signInButton);
mTextView = (TextView) mActivity.findViewById(R.id.linkContact);
}
问题:
以下代码行是引发错误的原因:
mActivity = Robolectric.buildActivity(
MainActivity.class).create().get();
最初,我尝试使用默认的 robolectricGradleTestRunner,但一直收到找不到的 ResourceNotFound com.my.app::string/app_name。在阅读了大量文章和博客之后,我遇到了 this 并且能够通过实现自定义 运行ner 来克服它。这在一定程度上解决了 app_name 问题。
如果在测试中 class 我把@config(sdk = 21) 我收到错误我
最初收到:
android.content.res.Resources$NotFoundException: 没有这样的标签 com.my.app:string/app_name
在 org.robolectric.util.ActivityController.getActivityTitle(ActivityController.java:104)
在 org.robolectric.util.ActivityController.attach(ActivityController.java:49)
在 org.robolectric.util.ActivityController$1.run(ActivityController.java:121)
在 org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:304)
在 org.robolectric.shadows.CoreShadowsAdapter$2.runPaused(CoreShadowsAdapter.java:45)
在 org.robolectric.util.ActivityController.create(ActivityController.java:118)
在 org.robolectric.util.ActivityController.create(ActivityController.java:129)
在 org.members1st.mobile.MainActivityTest.setup(MainActivityTest.java:32)
在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
在 org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
在 org.robolectric.RobolectricTestRunner.运行 孩子 (RobolectricTestRunner.java:188)
在 org.robolectric.RobolectricTestRunner.运行 孩子 (RobolectricTestRunner.java:54)
在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
在 org.junit.runners.ParentRunner.运行 儿童 (ParentRunner.java:288)
在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
在 org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
在 org.junit.runners.ParentRunner.运行(ParentRunner.java:363)
在 org.junit.runner.JUnitCore.run(JUnitCore.java:137)
在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
如果我单独留下 SDK,我得到 Robolectric doesn't support API 22
到目前为止我已经尝试过:
- 创建自定义 BuildConfig 并将其传递给每个
关于 this robolectric 线程的建议。
- 根据 this thread 上的建议在 @config 中设置 packageName。
- 重载新的 ApplicationManifest 以发回 api 级别
- 在我的 Gradle 文件中将 targetSdk 设置为 21
- 前面步骤的几乎所有组合都会导致相同的错误。
已验证 app_name 在测试构建生成的 values.xml 资源文件中
我试过使用
mActivity = Robolectric.setupActivity(MainActivity.class);
而不是
mActivity = Robolectric.buildActivity(
MainActivity.class).create().get();
8。 运行.
时,常规单元测试正常工作
你试过了吗
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk=21, packageName="com.my.app")
public class MainActivityTest
所以解决这个问题对我来说是一个面子,但希望能帮助其他人。
packageName 与 applicationId 不同。在大多数示例中,它们是相同的,所以我没有发现差异,直到我决定到底让我们尝试一下。
在上面,包名实际上是 org.my.app 但我的 applicationId 是 com.my.app
切换后一切都运行良好。真是菜鸟犯的错误!
这个问题我似乎无法解决,我已经阅读了大约 3 或 4 多篇文章和主题以试图解决它。我在下面概述了所有内容。
基本上问题是,我的 Robolectric 有问题吗?还是我遗漏了一些小步骤,或者我有一个奇怪的插件组合。对此的任何指导将不胜感激。
Windows 7 版本:
- Gradle 2.7
- Android Studio 1.3.2
- Robolectric 3.0
- Roboguice 3.+
项目依赖项:
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
classpath "com.newrelic.agent.android:agent-gradle-plugin:4.244.0"
classpath 'com.github.triplet.gradle:play-publisher:1.1.2'
classpath 'org.moallemi.gradle.advanced-build-version:gradle-plugin:1.5.0'
}
应用依赖项
import org.moallemi.gradle.internal.VersionCodeType
apply plugin: 'com.android.application'
apply plugin: 'newrelic'
apply plugin: 'com.github.triplet.play'
apply plugin: 'org.moallemi.advanced-build-version'
android {
def SERVICE_ACCOUNT = “account”;
def P12_KEY = file('mykey.p12')
signingConfigs {
releaseConfig {
…
}
}
compileSdkVersion 22
buildToolsVersion '22.0.1'
advancedVersioning {
nameOptions {
versionMajor 6
versionMinor advancedVersioning.versionCode
}
codeOptions {
versionCodeType VersionCodeType.AUTO_INCREMENT_ONE_STEP
}
}
defaultConfig {
applicationId "com.my.app ="
minSdkVersion 15
targetSdkVersion 22
versionCode = advancedVersioning.versionCode
versionName = advancedVersioning.versionName
}
buildTypes {
def STRING = "String"
def URL = "URL"
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.releaseConfig
}
staging {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
development {
minifyEnabled false
}
debug {
minifyEnabled false
}
}
testOptions {
unitTests.returnDefaultValues = true
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.android.gms:play-services:4.2.+'
compile(name: 'library-release', ext: 'aar')
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.google.code.gson:gson:2.3.1'
compile 'org.roboguice:roboguice:3.+'
provided 'org.roboguice:roboblender:3.+'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile "org.robolectric:robolectric:3.0"
}
repositories {
flatDir {
dirs 'libs'
}
}
自定义Gradle亚军
public class M1stRoboelectricGradleTestRunner extends RobolectricTestRunner {
public M1stRoboelectricGradleTestRunner(Class<?> testClass) throws InitializationError {
super(testClass);
String buildVariant = (BuildConfig.FLAVOR.isEmpty()
? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE;
String intermediatesPath = BuildConfig.class.getResource("")
.toString().replace("file:", "");
intermediatesPath = intermediatesPath
.substring(0, intermediatesPath.indexOf("/classes"));
System.setProperty("android.package",
BuildConfig.APPLICATION_ID);
System.setProperty("android.manifest",
intermediatesPath + "/manifests/full/"
+ buildVariant + "/AndroidManifest.xml");
System.setProperty("android.resources",
intermediatesPath + "/res/merged/" + buildVariant);
System.setProperty("android.assets",
intermediatesPath + "/assets/" + buildVariant);
}
@Override protected AndroidManifest getAppManifest(Config config) {
String manifestProperty = System.getProperty("android.manifest");
String resProperty = System.getProperty("android.resources");
String assetsProperty = System.getProperty("android.assets");
AndroidManifest manifest = new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
Fs.fileFromPath(assetsProperty)){
};
manifest.setPackageName("com.my.app");
return manifest;
}
}
测试Class
@RunWith(M1stRoboelectricGradleTestRunner.class)
public class MainActivityTest {
private MainActivity mActivity;
private Button mButton;
private TextView mTextView;
@Before
public void setup() {
mActivity = Robolectric.buildActivity(
MainActivity.class).create().get();
mButton = (Button) mActivity.findViewById(R.id.signInButton);
mTextView = (TextView) mActivity.findViewById(R.id.linkContact);
}
问题: 以下代码行是引发错误的原因:
mActivity = Robolectric.buildActivity(
MainActivity.class).create().get();
最初,我尝试使用默认的 robolectricGradleTestRunner,但一直收到找不到的 ResourceNotFound com.my.app::string/app_name。在阅读了大量文章和博客之后,我遇到了 this 并且能够通过实现自定义 运行ner 来克服它。这在一定程度上解决了 app_name 问题。
如果在测试中 class 我把@config(sdk = 21) 我收到错误我 最初收到:
android.content.res.Resources$NotFoundException: 没有这样的标签 com.my.app:string/app_name 在 org.robolectric.util.ActivityController.getActivityTitle(ActivityController.java:104) 在 org.robolectric.util.ActivityController.attach(ActivityController.java:49) 在 org.robolectric.util.ActivityController$1.run(ActivityController.java:121) 在 org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:304) 在 org.robolectric.shadows.CoreShadowsAdapter$2.runPaused(CoreShadowsAdapter.java:45) 在 org.robolectric.util.ActivityController.create(ActivityController.java:118) 在 org.robolectric.util.ActivityController.create(ActivityController.java:129) 在 org.members1st.mobile.MainActivityTest.setup(MainActivityTest.java:32) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) 在 org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251) 在 org.robolectric.RobolectricTestRunner.运行 孩子 (RobolectricTestRunner.java:188) 在 org.robolectric.RobolectricTestRunner.运行 孩子 (RobolectricTestRunner.java:54) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.运行 儿童 (ParentRunner.java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152) 在 org.junit.runners.ParentRunner.运行(ParentRunner.java:363) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) 在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
如果我单独留下 SDK,我得到 Robolectric doesn't support API 22
到目前为止我已经尝试过:
- 创建自定义 BuildConfig 并将其传递给每个 关于 this robolectric 线程的建议。
- 根据 this thread 上的建议在 @config 中设置 packageName。
- 重载新的 ApplicationManifest 以发回 api 级别
- 在我的 Gradle 文件中将 targetSdk 设置为 21
- 前面步骤的几乎所有组合都会导致相同的错误。
已验证 app_name 在测试构建生成的 values.xml 资源文件中
我试过使用
mActivity = Robolectric.setupActivity(MainActivity.class);
而不是
mActivity = Robolectric.buildActivity(
MainActivity.class).create().get();
8。 运行.
时,常规单元测试正常工作你试过了吗
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk=21, packageName="com.my.app")
public class MainActivityTest
所以解决这个问题对我来说是一个面子,但希望能帮助其他人。
packageName 与 applicationId 不同。在大多数示例中,它们是相同的,所以我没有发现差异,直到我决定到底让我们尝试一下。
在上面,包名实际上是 org.my.app 但我的 applicationId 是 com.my.app
切换后一切都运行良好。真是菜鸟犯的错误!