Kotlin / anko

Pleasant Android application development
Apache License 2.0
15.88k stars 1.29k forks source link

Unit test fails using uiThread() inside doAsync() #505

Open francos opened 6 years ago

francos commented 6 years ago

I'm creating some unit tests for my Android app logic and I'm stuck trying to figure out how to make uiThread() work in them.

The code I have is very basic:

doAsync {
    // Update the DB

    uiThread {
        // Update LiveData
    }
}

and the error I'm getting is:

java.lang.ExceptionInInitializerError
    at org.jetbrains.anko.AsyncKt.uiThread(Async.kt:67)
...
Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
    at android.os.Looper.getMainLooper(Looper.java)
    at org.jetbrains.anko.ContextHelper.<init>(Async.kt:209)
    at org.jetbrains.anko.ContextHelper.<clinit>(Async.kt:208)
    ... 12 more

Any idea how I can make this work?

Ant8 commented 6 years ago

just a wild a** guess, but perhaps InstrumentationRegistry.getInstrumentation().runOnMainSync { } would help? Or better yet, externalising executor/thread pools and providing them to doAsync?

francos commented 6 years ago

Thanks for the answer @Ant8. In the end, I ended up moving to coroutines as I thought it was interesting to learn how to use them. I still had this issue in a different way (when using the UI constant that is used to run a coroutine on the main thread), so I created some custom code to use my own constant instead of UI so that I could override it in tests.

I hope your answer can help other people that are having this issue!