Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override Robolectric application?

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)
like image 810
Ritave Avatar asked Dec 11 '22 18:12

Ritave


1 Answers

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;
    }
}
like image 102
Ritave Avatar answered Dec 29 '22 18:12

Ritave