Android Studio - Robolectric:android.content.res.Resources $ NotFoundException:没有这样的标签com.my.app:string/app_name

ami*_*ner 11 android robolectric android-studio

这个问题我似乎无法摆脱,我已经经历了大概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'
}
Run Code Online (Sandbox Code Playgroud)

应用程序依赖项

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'
}
}
Run Code Online (Sandbox Code Playgroud)

自定义Gradle Runner

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;
}
}
Run Code Online (Sandbox Code Playgroud)

测试类

@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);
}
Run Code Online (Sandbox Code Playgroud)

问题:以下代码行是抛出错误的原因:

 mActivity = Robolectric.buildActivity(
    MainActivity.class).create().get();
Run Code Online (Sandbox Code Playgroud)

最初,我尝试使用默认的robolectricGradleTestRunner,但仍然收到未找到的ResourceNotFound com.my.app::string/app_name.在仔细阅读了大量的文章和博客之后,我遇到了这个并且能够通过实现自定义运行器来克服它.这解决了app_name问题.

  1. 如果在测试类上我放了@config(sdk = 21)我收到了我最初收到的错误:

    android.content.res.Resources $ NotFoundException:在org.robolectric.util.ActivityController.attach的org.robolectric.util.ActivityController.getActivityTitle(ActivityController.java:104)中没有这样的标签com.my.app:string/app_name( ActivityController.java:49)org.robolectric.util.ActivityController $ 1.run(ActivityController.java:121)atg.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:304)org.robolectric.shadows.CoreShadowsAdapter $ 2 .runPaused(CoreShadowsAdapter.java:45)位于org.members1st.mobile的org.robolectric.util.ActivityController.create(ActivityController.java:118)org.robolectric.util.ActivityController.create(ActivityController.java:129). MainActivityTest.setup(MainActivityTest.java:32)位于sun.reflect.NativeMethodAccessorImpl的sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method).在org.junit.internal的org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50)的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中调用(NativeMethodAccessorImpl.java:62). runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores. java:24)at org.robolectric.RobolectricTestRunner $ 2.evaluate(RobolectricTestRunner.java:251)org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(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.run(ParentRunner.java:363)在org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.Junit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)at com.intellij.rt.exe.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)at com.intellij.rt.execution.junit.JUnitStarter .主要(JUnitStarter.java:68)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在com.intellij.rt.execution.application.AppMain.主(AppMain.java:140)

  2. 如果我单独留下SDK,我会得到Robolectric不支持API 22

到目前为止,我已经尝试过:

  1. 创建自定义BuildConfig并通过在每建议, robolectric线程的.
  2. 此线程的每个推荐的@config中设置packageName.
  3. 重载新的ApplicationManifest以发送回api级别
  4. 在我的Gradle文件中将targetSdk设置为21
  5. 几乎所有前面步骤的组合都会导致相同的错误.
  6. 验证app_name位于测试版本生成的values.xml资源文件中

  7. 我试过用了

    mActivity = Robolectric.setupActivity(MainActivity.class);

代替

mActivity = Robolectric.buildActivity(
    MainActivity.class).create().get();
Run Code Online (Sandbox Code Playgroud)

8.正常的单元测试在运行时正在运行.

Ste*_*e C 9

你有没有尝试过

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk=21, packageName="com.my.app")
public class MainActivityTest
Run Code Online (Sandbox Code Playgroud)


ami*_*ner 2

因此,这个解决方案对我来说是一个打击,但希望对其他人有所帮助。

packageName与 applicationId 不同在大多数例子中,它们是相同的,所以我没有发现差异,直到我决定到底要尝试什么。

在上面,包名称实际上是 org.my.app 但我的 applicationId 是 com.my.app

一旦切换,一切都工作得很好。这是一个菜鸟错误!