Java 使用Robolectric测试Android应用程序

Java 使用Robolectric测试Android应用程序,java,android,gradle,android-studio,robolectric,Java,Android,Gradle,Android Studio,Robolectric,事实上,我有两个关于机器人分子的问题 一个小的介绍: 我的申请分为三类。一个应用程序(类MyApp)、一个活动(类MainActivity)和一个类(类InAppConfig),以及我在application.onCreate方法中初始化的一些设置(它们都保存为静态字段)。现在关于测试部分。让我们把它看作是一个具有多个测试方法的单一测试类 第一个问题是RobolectrictTestRunner为每个测试方法创建一个MyApp类的新实例(这会导致InAppConfig的多次初始化)。这在我的情况

事实上,我有两个关于机器人分子的问题

一个小的介绍:

我的申请分为三类。一个应用程序(类MyApp)、一个活动(类MainActivity)和一个类(类InAppConfig),以及我在application.onCreate方法中初始化的一些设置(它们都保存为静态字段)。现在关于测试部分。让我们把它看作是一个具有多个测试方法的单一测试类

第一个问题是RobolectrictTestRunner为每个测试方法创建一个MyApp类的新实例(这会导致InAppConfig的多次初始化)。这在我的情况下是不可接受的,我正在寻找任何不涉及更改测试中应用程序代码的解决方案

第二个问题是,每次尝试在测试中启动一个活动时,我都会遇到一个异常(参考资料$NotFoundException)。我是这样做的:

private final ActivityController<MainActivity> controller = Robolectric.buildActivity(MainActivity.class);
...
final MainActivity activity = controller.create().start().resume().get();
apply plugin: 'com.android.application'
apply plugin: 'robolectric'

android {
    compileSdkVersion rootProject.compileSdkVersion
    buildToolsVersion rootProject.buildToolsVersion

    defaultConfig {
        minSdkVersion rootProject.minSdkVersion
        targetSdkVersion rootProject.targetSdkVersion
        versionCode 20
        versionName '0.9.8.2'

        // applicationId 'my.package.org'
    }
 ...
}
但是,当然,我想在构建文件中保留applicationId,所以这仍然是一个问题。 此外,Robolectrics git repo上似乎有一个与同一问题相关的未决问题。()

如果你对如何解决这些问题有任何想法,请告诉我。提前谢谢

编辑:

下面附上第二期的stacktrace:

android.content.res.Resources$NotFoundException: no such label my.package.org:string/title_activity_main
    at org.robolectric.util.ActivityController.getActivityTitle(ActivityController.java:97)
    at org.robolectric.util.ActivityController.attach(ActivityController.java:44)
    at org.robolectric.util.ActivityController$1.run(ActivityController.java:114)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:268)
    at org.robolectric.util.ActivityController.create(ActivityController.java:111)
    at org.robolectric.util.ActivityController.create(ActivityController.java:122)
    at org.onepf.sample.trivialdrive.ActivityInitTest.test1(ActivityInitTest.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
    at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

请输入stacktrace以了解您遇到的异常情况,否则我们将无能为力。另外,当你单独问每个问题时,你会得到最好的答案,这使你更容易自己回答和讨论每个问题。@AlexFlorescu,我添加了stacktrace。Roboletric用于单元测试。在每个测试用例之前初始化应用程序是一种很好的方法,因为它可以在测试之间提供隔离和独立状态。如果你想进行单元测试,你必须测试一小段代码。如果你想让测试更具功能性,看看安卓仪器。使用类似Robolectric的东西通常意味着不同的应用程序架构,以帮助测试更容易;在Roboguice中使用依赖项注入和/或在测试清单中指定不同的应用程序类,可以避免启动配置问题,但必须更改应用程序代码。