I have something like the following in Kotlin:
class A {
fun a(): Unit = TODO()
}
fun foo(a: A) {
// Do something
CoroutineScope(Dispatchers.IO).launch {
delay(1000)
a.a()
}
// Do something else
}
I want to write a test that verifies that the method A.a()
was called by foo()
:
class MyTest {
@Test
fun `weird test`() {
val mockA: A = mockk(relaxed = true)
foo(mockA)
verify(exactly = 1) { mockA.a() }
}
}
Clearly, the test is failing because it is not synchronized with the coroutine. I tried to use runTest
, but foo()
is not a suspending function, and it is hiding the creation of the scope inside it.
What can I do?
TODO()
produces an error, that only lets the coroutine fail. The test itself is successfully completed, without any failures. This is all expected, the code you provided does not reproduce the problem you describe, Please edit again to either provide code that matches the behavior you describe or clarify what issues you have with the current code, since it does work. -- Btw., you should either make the function suspending or pass it a CoroutineScope. Otherwise you cannot control the coroutine from the outside, which is usually necessary.delay(1000)
beforea.a()
then the test will fail due to the issue that you've described. I've made changes in the answerA.a()
is mocked, sodelay(1000)
never runs. You need to use a spy forA
or go with my earlier suggestion