I am looking for a better way to test coroutine. Currently, I'm using Turbine as the test helper. However, I have some difficulty improving the timeout issue.
ex:
class RepositoryTest {
@get:Rule
val rule = InstantTaskExecutorRule()
private lateinit var sut: SubjectToTest
private val testDispatchers = TestDispatchersProvider.dispatchers
private val mockAddressRepository = mockk<AddressRepository>(relaxed = true)
private val mockApiService = mockk<ApiService>(relaxed = true)
private val mockCardsRepository = mockk<CardsRepository>(relaxed = true)
@Before
fun setup() {
sut = SutRepository(
apiService = mockApiService,
dispatchersProvider = testDispatchers,
restCallHandler = testRestCallHandler,
addressRepo = mockAddressRepository,
cardRepo = mockCardsRepository,
)
}
@After
fun tearDown() {
unmockkAll()
}
private val mockCardResponse = CardResponse(
data = DataModel(
listOf(
...
)
)
)
@Test
fun `fetchData has success response then return Data`() = runBlockingTest {
// Given
coEvery {
mockAddressService.fetchAddresss(any(), any(), any(), any(), any(), any(), any())
} returns Response.success(mockCardResponse)
every {
mockCardsRepository.fetchCard
} returns mockFlow()
testRestCallHandler.callResult = ...
// Test
sut.fetchMessages(true)
sut.StateFlow.test {
expectItem().assertObject{ ... }
expectItem().assertSize(1)
}
}
}
the code above, has TimeoutCancellationException.
kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1000 ms
at |b|b|b(Coroutine boundary.|b(|b)
by solving the above issue, I move the class initialization in the test.
@Test
fun `fetchData has success response then return Data`() = runBlockingTest {
// Given
coEvery {
mockAddressService.fetchAddresss(any(), any(), any(), any(), any(), any(), any())
} returns Response.success(mockCardResponse)
every {
mockCardsRepository.fetchCard
} returns mockFlow()
testRestCallHandler.callResult = ...
// Test
sut = SutRepository(
apiService = mockApiService,
dispatchersProvider = testDispatchers,
restCallHandler = testRestCallHandler,
addressRepo = mockAddressRepository,
cardRepo = mockCardsRepository,
)
sut.fetchMessages(true)
sut.StateFlow.test {
expectItem().assertType<List<DataMode>> {
this.assertListSize(1)
}
cancel()
}
}
after moving the initialization in the test, the test pass but I am looking for a way to improve it.