I've inherited legacy Android project and started to add Robolectric 3 and JUnit 4 test cases. Sadly currently the main Application class can't be initialized because of spaghetti code and frameworks that don't work in Robolectric. I'd like to replace my application class for the tests. But Robolectric crashes before I can even update the RuntimeEnviroment.application
variable.
Is there a way to disable manifest application creation in Robolectric?
Here's what I've been trying to do:
@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
}
}
But it fails due to Parse framework:
java.lang.RuntimeException
at org.robolectric.util.SimpleFuture.run(SimpleFuture.java:61)
at org.robolectric.shadows.ShadowAsyncTask$2.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$2.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$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: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$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.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)
So it happens that Robolectric developers forsaw this situation and @Config
directive allows application override. Also manifest override didn't help me at all so it could be removed.
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21, application = MyTestApplication.class)
public class TestClass {
@Test
public void testFunc() {
// some testing goes here
}
}
Since our application uses singleton pattern I had to also init singleton instance. I ignore all other initalization on purpouse since it was mostly initting frameworks. Here's what my MyTestApplication looks like:
public class MyTestApplication extends MyApplication {
@Override
public void onCreate() {
MyApplication.instance = this;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With