如何解决Kotlin Flow Unit测试异常以及使用带有不同分派器的FlowOn进行的工作
使用下面的代码测试Flow
和MockK
的异常
@测试
有趣的given network error returned from repos,should throw exception
()=
testCoroutineScope.runBlockingTest {
// GIVEN
every { postRemoteRepository.getPostFlow() } returns flow<List<PostDTO>> {
emit(throw Exception("Network Exception"))
}
// WHEN
var expected: Exception? = null
useCase.getPostFlow()
.catch { throwable: Throwable ->
expected = throwable as Exception
println("⏰ Expected: $expected")
}
.launchIn(testCoroutineScope)
// THEN
println("⏰ TEST THEN")
Truth.assertThat(expected).isNotNull()
Truth.assertThat(expected).isInstanceOf(Exception::class.java)
Truth.assertThat(expected?.message).isEqualTo("Network Exception")
}
并打印
⏰ TEST THEN
⏰ Expected: java.lang.Exception: Network Exception
测试失败
expected not to be: null
我测试的方法是
fun getPostFlow(): Flow<List<Post>> {
return postRemoteRepository.getPostFlow()
// ? This method is just to show flowOn below changes current thread
.map {
// Runs in IO Thread DefaultDispatcher-worker-2
println("⏰ PostsUseCase map() FIRST thread: ${Thread.currentThread().name}")
it
}
.flowOn(Dispatchers.IO)
.map {
// Runs in Default Thread DefaultDispatcher-worker-1
println("⏰ PostsUseCase map() thread: ${Thread.currentThread().name}")
mapper.map(it)
}
// This is a upstream operator,does not leak downstream
.flowOn(Dispatchers.Default)
}
这不是一个完全实用的功能,而只是检查Dispatchers如何处理Flow和测试。
在撰写问题时,我已将.flowOn(Dispatchers.IO)
注释掉,其中最上面的一个
测试通过了。还将Dispatchers.IO更改为Dispatchers.Default并导致测试通过。我认为这是由于使用了不同的线程。
1-是否存在将所有flowOn方法设置为同一线程而不修改代码的函数或方法?
这次我尝试使用以下方法测试成功场景
@Test
fun `given data returned from api,should have data`() = testCoroutineScope.runBlockingTest {
// GIVEN
coEvery { postRemoteRepository.getPostFlow() } returns flow { emit(postDTOs) }
every { dtoToPostMapper.map(postDTOs) } returns postList
val actual = postList
// WHEN
val expected = mutableListOf<Post>()
// useCase.getPostFlow().collect {postList->
// println("⏰ Collect: ${postList.size}")
//
// expected.addAll(postList)
// }
val job = useCase.getPostFlow()
.onEach { postList ->
println("⏰ Collect: ${postList.size}")
expected.addAll(postList)
}
.launchIn(testCoroutineScope)
job.cancel()
// THEN
println("⏰ TEST THEN")
Truth.assertThat(expected).containsExactlyElementsIn(actual)
}
当我尝试摘录的片段时,测试失败并
java.lang.IllegalStateException: This job has not completed yet
如果job
被取消,则带有launchIn
且返回job
的测试似乎可以通过。
2-为什么不取消使用收集作业,而仅在第一个flowOn
使用Dispatchers.IO
时发生?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。