I am writing a test and I get this error from a standard library:
java.lang.IllegalStateException: Method addObserver must be called on the main thread
This is my simplified test method:
@Test
fun useAppContext() = runTest {
assert(isMainThread())
}
How can I make this test succeed? I need to add an observer somewhere in my test which fails because I need to do so on the main thread.
Like
runBlocking(and like code written directly in@Testmethods), code withinrunTestis run on the test thread by default, rather than on the main thread. This is usually the behavior you want, because if you don't yield the main thread, it will not run layouts, and your UI will be completely frozen.To run a specific part of your test on the UI thread
If you just have a specific part of your test that should be run on the UI thread, such as your example of the
addObservercall, you can switch the coroutine dispatcher for that specific part of the test.Surround the relevant part of your method with
withContext(Dispatchers.Main)To run your entire test on the UI thread
If you do want to run your test on the main thread (for example, because it's a simple test that doesn't involve any layouts, or because you want to manually control when you yield the main thread with
suspendmethods (such as Compose'swithFrameNanos), this can be done with the@UiThreadTestannotation.Annotate the test method (or the class, if all
@Test,@Before, and@Aftermethods should be run on the UI thread) with@UiThreadTest.