問題タブ [kotlin-flow]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
android - Kotlin コルーチンを使用して Android 単体テストに viewModelScope を挿入するにはどうすればよいですか?
質問
viewModelScope
Kotlinコルーチンを使用してAndroid単体テストに注入するための最良の戦略は何ですか?単体テストのために CoroutineScope が ViewModel に挿入されるとき、CoroutineDispatcher も挿入され
flowOn
、実稼働コードで必要とされない場合でも使用して定義されるべきですか?
flowOn
Dispatchers.IO
RetrofitはSomeRepository.ktでスレッド化を処理し、viewModelScope
は でデータを返すため、このユース ケースのプロダクション コードでは必要ありませんDispathers.Main
。どちらもデフォルトで行われます。
期待される
Kotlin Flow 値に保存された Android の ViewModel ビューステート値で単体テストを実行します。
観察した
メイン ディスパッチャを含むモジュールの初期化に失敗しました。テストには、kotlinx-coroutines-test モジュールの Dispatchers.setMain を使用できます
CoroutineScope がハードコードされている最初の発生時に、単体テストが失敗します。viewModelScope
起動されたコルーチンが ViewModel のライフサイクルを維持するように利用されます。ただし、viewModelScope
ViewModel 内から作成されるため、ViewModel の外部で定義して引数として渡すことができる CoroutineDispatcher と比較して、注入がより複雑になります。
実装
SomeViewModel.kt
SomeTest.kt
注: JUnit 5 テスト拡張機能は、最終バージョンで使用されます。
完全なエラー ログ
スレッド「main @coroutine#1」での例外 java.lang.IllegalStateException: メイン ディスパッチャを含むモジュールの初期化に失敗しました。テストでは、kotlinx-coroutines-test モジュールの Dispatchers.setMain を kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.missing(MainDispatchers.kt:113) で使用できます。 kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:285) kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26) kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109) at kotlinx.coroutines .AbstractCoroutine.start(AbstractCoroutine.kt:158) at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders. 68) com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) で com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) で com.intellij.rt.junit で.JUnitStarter.main(JUnitStarter.java:58) 原因: java.lang.RuntimeException: android.os.Looper のメソッド getMainLooper がモックされていません。見るhttp://g.co/androidstudio/not-mocked詳細については。android.os.Looper.getMainLooper(Looper.java) で kotlinx.coroutines.android.AndroidDispatcherFactory.createDispatcher(HandlerDispatcher.kt:55) で kotlinx.coroutines.android.AndroidDispatcherFactory.createDispatcher(HandlerDispatcher.kt:52) で kotlinx. coroutines.internal.MainDispatchersKt.tryCreateDispatcher(MainDispatchers.kt:57) at kotlinx.coroutines.test.internal.TestMainDispatcher.getDelegate(MainTestDispatcher.kt:19) at kotlinx.coroutines.test.internal.TestMainDispatcher.getImmediate(MainTestDispatcher.kt: 32) androidx.lifecycle.ViewModelKt.getViewModelScope(ViewModel.kt:42) で ... スレッド「main @coroutine#1」で 40 以上の例外 java.lang.IllegalStateException: Main ディスパッチャを持つモジュールの初期化に失敗しました。テストディスパッチャ用。com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58) の prepareStreamsAndStart(JUnitStarter.java:230) 原因: java.lang.RuntimeException: android.os.Looper のメソッド getMainLooper がモックされていません。見る詳細については、http: //g.co/androidstudio/not-mockedをご覧ください。android.os.Looper.getMainLooper(Looper.java) で kotlinx.coroutines.android.AndroidDispatcherFactory.createDispatcher(HandlerDispatcher.kt:55) で kotlinx.coroutines.android.AndroidDispatcherFactory.createDispatcher(HandlerDispatcher.kt:52) で kotlinx. coroutines.internal.MainDispatchersKt.tryCreateDispatcher(MainDispatchers.kt:57) at kotlinx.coroutines.test.internal.TestMainDispatcher.getDelegate(MainTestDispatcher.kt:19) at kotlinx.coroutines.test.internal.TestMainDispatcher.getImmediate(MainTestDispatcher.kt: 32) app.topcafes.feed.viewmodel.FeedViewModel.bindIntents(FeedViewModel.kt:38) で androidx.lifecycle.ViewModelKt.getViewModelScope(ViewModel.kt:42) ... 39 もっと見る
android - Kotlin Flow toList() を使用した Android Room ライブラリが機能しない
Room と Flows を使用して簡単なサンプル アプリを作成しました。
上記のコードのように関数を使用したいのですtoList()
が、何か問題が発生し、ログでさえ印刷されません。同時に、使用collect()
すると正常に動作し、すべてのレコードが得られます。
誰が私に何が悪いのか説明できますか? ありがとう。
android - 複数のフローを組み合わせる> 単一の流れへ
Room データベースの異なる @Query からの複数の Flow 結果を、それらの結果リストの Map の Flow に変換しようとしています。このようなもの:
私はこのようなことをしてみました:
しかし、明らかにそれは機能していないようです。どうすればこれを達成できるかについてのアイデア。よろしくお願いします
kotlin - Kotlinでいくつかのサブスクリプションを持つフローを作成するには?
データを出力するタスクを実行する必要があります。このデータを PublishSubject のようにサブスクライブしたいと考えています。しかし、ワンインスタンス フローの問題は解決できません。もう一度呼び出そうとすると、別のインスタンスが作成され、ジョブが 2 回実行されます。フローを内部で実行し、BroadcastChannel に値をポストしようとしましたが、この解決策は正しくないようです。そのようなタスクのベストプラクティスは何ですか?