最近最近でした 紹介された コトリンコルーチンの一部としてクラスStateFlow
。
私は現在それを試して、私のViewModelをテストしようとしている間に問題を見つめています。私が達成したいのです:私のStateFlow
が私のViewModelの正しい順序ですべての状態値を受け取っていることをテストします。
私のコードは以下の通りです:
ビューモーデル:
_class WalletViewModel(private val getUserWallets: GetUersWallets) : ViewModel() {
val userWallet: StateFlow<State<UserWallets>> get() = _userWallets
private val _userWallets: MutableStateFlow<State<UserWallets>> =
MutableStateFlow(State.Init)
fun getUserWallets() {
viewModelScope.launch {
getUserWallets.getUserWallets()
.onStart { _userWallets.value = State.Loading }
.collect { _userWallets.value = it }
}
}
_
私のテスト:
_ @Test
fun `observe user wallets ok`() = runBlockingTest {
Mockito.`when`(api.getAssetWallets()).thenReturn(TestUtils.getAssetsWalletResponseOk())
Mockito.`when`(api.getFiatWallets()).thenReturn(TestUtils.getFiatWalletResponseOk())
viewModel.getUserWallets()
val res = arrayListOf<State<UserWallets>>()
viewModel.userWallet.toList(res) //doesn't works
Assertions.assertThat(viewModel.userWallet.value is State.Success).isTrue() //works, last value enmited
}
_
最後の値にアクセスされた作品にアクセスします。しかし、私がテストしたいのは、すべての放出された値が正しい順序で放出されることです。このコードで:viewModel.userWallet.toList(res) //doesn't works
次のエラーが発生しました:
_Java.lang.IllegalStateException: This job has not completed yet
at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1189)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)
at WalletViewModelTest.observe user wallets ok(WalletViewModelTest.kt:52)
....
_
私は私が明白なものを逃していると思います。しかし、私がコルーチンとフローを始めるだけで、RunBlockingTestを使用していないときにこのエラーが発生しているようです。
編集:一時的な解決策として、ライブデータとしてテストしています。
_ @Captor
lateinit var captor: ArgumentCaptor<State<UserWallets>>
@Mock
lateinit var walletsObserver: Observer<State<UserWallets>>
@Test
fun `observe user wallets ok`() = runBlockingTest {
viewModel.userWallet.asLiveData().observeForever(walletsObserver)
viewModel.getUserWallets()
captor.run {
Mockito.verify(walletsObserver, Mockito.times(3)).onChanged(capture())
Assertions.assertThat(allValues[0] is State.Init).isTrue()
Assertions.assertThat(allValues[1] is State.Loading).isTrue()
Assertions.assertThat(allValues[2] is State.Success).isTrue()
}
}
_
あなたが直面している問題は、tolist()が完了するフローを必要とし、ドキュメントに従って "State Flowが完了しない"を必要とするからです。