如何覆盖 Robolectric 应用程序?
How to override Robolectric application?
我继承了遗留的 Android 项目并开始添加 Robolectric 3 和 JUnit 4 测试用例。遗憾的是,目前无法初始化主应用程序 class,因为意大利面条式代码和框架在 Robolectric 中不起作用。我想替换我的应用程序 class 进行测试。但是 Robolectric 在我更新 RuntimeEnviroment.application
变量之前就崩溃了。
有没有办法在 Robolectric 中禁用清单应用程序创建?
这是我一直在尝试做的事情:
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21, manifest = Config.NONE)
public class TestClass {
@Before
public void setUp() {
RuntimeEnvironment.application = new Application();
}
@Test
public void testFunc() {
// some testing goes here
}
}
但由于 Parse 框架,它失败了:
java.lang.RuntimeException
at org.robolectric.util.SimpleFuture.run(SimpleFuture.java:61)
at org.robolectric.shadows.ShadowAsyncTask.run(ShadowAsyncTask.java:96)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:230)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:85)
at org.robolectric.util.Scheduler.post(Scheduler.java:72)
at org.robolectric.shadows.ShadowAsyncTask.execute(ShadowAsyncTask.java:93)
at android.os.AsyncTask.execute(AsyncTask.java)
at com.facebook.internal.Utility.loadAppSettingsAsync(Utility.java:771)
at com.facebook.FacebookSdk.sdkInitialize(FacebookSdk.java:167)
at com.facebook.FacebookSdk.sdkInitialize(FacebookSdk.java:146)
at com.parse.FacebookController$FacebookSdkDelegateImpl.initialize(FacebookController.java:187)
at com.parse.FacebookController.initialize(FacebookController.java:70)
at com.parse.ParseFacebookUtils.initialize(ParseFacebookUtils.java:108)
at com.parse.ParseFacebookUtils.initialize(ParseFacebookUtils.java:92)
at MyApplication.initParse(StrongliftsApplication.java:174)
at MyApplication.onCreate(StrongliftsApplication.java:112)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433)
at org.robolectric.RobolectricTestRunner.evaluate(RobolectricTestRunner.java:240)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
所以 Robolectric 开发人员预见到了这种情况,@Config
指令允许应用程序覆盖。此外,清单覆盖对我没有任何帮助,因此可以将其删除。
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21, application = MyTestApplication.class)
public class TestClass {
@Test
public void testFunc() {
// some testing goes here
}
}
由于我们的应用程序使用单例模式,因此我还必须初始化单例实例。我故意忽略所有其他初始化,因为它主要是初始化框架。这是我的 MyTestApplication 的样子:
public class MyTestApplication extends MyApplication {
@Override
public void onCreate() {
MyApplication.instance = this;
}
}
有一个更简单的解决方案。
只需将 class Test<YouApplicationName>
放入测试源中,**Robolectric 就会提取它。
因此,如果您的应用程序名称是 org.my.package.SuperApplication
,则在文件夹 test\java\org\my\package\
中创建 class TestSuperapplication
,您无需在 [=14= 中提供任何内容] 部分。
我继承了遗留的 Android 项目并开始添加 Robolectric 3 和 JUnit 4 测试用例。遗憾的是,目前无法初始化主应用程序 class,因为意大利面条式代码和框架在 Robolectric 中不起作用。我想替换我的应用程序 class 进行测试。但是 Robolectric 在我更新 RuntimeEnviroment.application
变量之前就崩溃了。
有没有办法在 Robolectric 中禁用清单应用程序创建?
这是我一直在尝试做的事情:
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21, manifest = Config.NONE)
public class TestClass {
@Before
public void setUp() {
RuntimeEnvironment.application = new Application();
}
@Test
public void testFunc() {
// some testing goes here
}
}
但由于 Parse 框架,它失败了:
java.lang.RuntimeException
at org.robolectric.util.SimpleFuture.run(SimpleFuture.java:61)
at org.robolectric.shadows.ShadowAsyncTask.run(ShadowAsyncTask.java:96)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:230)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:85)
at org.robolectric.util.Scheduler.post(Scheduler.java:72)
at org.robolectric.shadows.ShadowAsyncTask.execute(ShadowAsyncTask.java:93)
at android.os.AsyncTask.execute(AsyncTask.java)
at com.facebook.internal.Utility.loadAppSettingsAsync(Utility.java:771)
at com.facebook.FacebookSdk.sdkInitialize(FacebookSdk.java:167)
at com.facebook.FacebookSdk.sdkInitialize(FacebookSdk.java:146)
at com.parse.FacebookController$FacebookSdkDelegateImpl.initialize(FacebookController.java:187)
at com.parse.FacebookController.initialize(FacebookController.java:70)
at com.parse.ParseFacebookUtils.initialize(ParseFacebookUtils.java:108)
at com.parse.ParseFacebookUtils.initialize(ParseFacebookUtils.java:92)
at MyApplication.initParse(StrongliftsApplication.java:174)
at MyApplication.onCreate(StrongliftsApplication.java:112)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433)
at org.robolectric.RobolectricTestRunner.evaluate(RobolectricTestRunner.java:240)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
所以 Robolectric 开发人员预见到了这种情况,@Config
指令允许应用程序覆盖。此外,清单覆盖对我没有任何帮助,因此可以将其删除。
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21, application = MyTestApplication.class)
public class TestClass {
@Test
public void testFunc() {
// some testing goes here
}
}
由于我们的应用程序使用单例模式,因此我还必须初始化单例实例。我故意忽略所有其他初始化,因为它主要是初始化框架。这是我的 MyTestApplication 的样子:
public class MyTestApplication extends MyApplication {
@Override
public void onCreate() {
MyApplication.instance = this;
}
}
有一个更简单的解决方案。
只需将 class Test<YouApplicationName>
放入测试源中,**Robolectric 就会提取它。
因此,如果您的应用程序名称是 org.my.package.SuperApplication
,则在文件夹 test\java\org\my\package\
中创建 class TestSuperapplication
,您无需在 [=14= 中提供任何内容] 部分。