🧪
Kotlin FlowのエラーケースのUnit testでハマって解消した
事象
kotlin.testとMockKとTubineを使用して
interface UserRepository {
fun observeUsers(): Flow<Result<List<User>>>
}
のようなFlowを返す関数をラップしたObserveUsersUseCase
のテストコードを
@Test
fun observeUsers_failure() {
coEvery { userRepository.observeUsers() } throws Exception("result failure")
runTest {
val result = observeUsersUseCase()
coVerify(exactly = 1) { userRepository.observeUsers() }
result.test {
assertIs<Result.Error>(awaitItem())
awaitComplete()
}
}
}
このような感じに書いていたのですが、
java.lang.Exception: result failure
ってそのままExceptionが出てしまいテストが失敗していました。
対応
- coEvery { userRepository.observeUsers() } throws Exception("result failure")
+ coEvery { userRepository.observeUsers() } returns flow { Exception("result failure") }
が正解でした。
そもそもFlowの中でExceptionが出る訳なんだけど、ハマると分からなくなるよねって話でした。
kotlin.test
便利
余談:kotlin.testのassertIs<T>()
って便利ですね
今までJUnitを使っていたので↓みたいに書いてました。
assert(awaitItem() is Result.Error)
まぁ以前、参画していたプロジェクトではKotestを使用していたのでshouldBeTypeOf<T>()
を使っていましたが、公式のkotlin.test
でサポートされてる方が今後何かと便利ですよねー。
参考
Discussion