In my Android Kotlin project, I have a class, with a function running a coroutine, that I want to test using an instrumented test (not unit test).
Here is what it looks like:
class DemoClass
{
fun demo(liveData: MutableLiveData<String>)
{
CoroutineScope(IO).launch {
val result = doStuff()
withContext(Main) { liveData.value = result }
}
}
}
In my instrumented test class, here is what I tried:
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest
{
@ExperimentalCoroutinesApi
@Test
fun testCoroutine() = runBlockingTest {
val demoClass = DemoClass()
val liveData = MutableLiveData<String>()
demoClass.demo(liveData)
assertEquals("demo", liveData.value)
}
}
Unfortunately, it's not working. It seems like runBlockingTest {}
is only available for unit testing, not instrumented testing. Here is my error when I run the test:
java.lang.NoClassDefFoundError: Failed resolution of: Lkotlinx/coroutines/test/TestBuildersKt;
So how can I test DemoClass.demo()
and the liveData
value in an instrumented test?
Thanks.
EDIT
I also tried this:
@ExperimentalCoroutinesApi
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest
{
private val testDispatcher = TestCoroutineDispatcher()
@Before
fun setup() {
Dispatchers.setMain(testDispatcher)
}
@After
fun tearDown() {
Dispatchers.resetMain()
testDispatcher.cleanupTestCoroutines()
}
@Test
fun testCoroutine(): Unit = runBlocking {
val demoClass = DemoClass()
val liveData = MutableLiveData<String>()
demoClass.demo(liveData)
assertEquals("demo", liveData.value)
}
}
The test runs, but I got this:
java.lang.AssertionError:
Expected :demo
Actual :null