追記: この記事は古くなってますので、以下のドキュメントを参考にしてください。
まだよく分かってないこと多いですが、試したことをメモしておきます。
Android Studioでの実行を想定しています。また、AssertionはTruthを使ってます。
単純なsuspend関数
テスト対象
テストコード
単純なsuspend関数はテストメソッドを runBlocking
で囲むだけで大丈夫です。
withContext
テスト対象
テストコード
suspend関数内でwithContextでDispatcherを切り替えてるものも、同様に runBlocking
で囲むだけです。
注意として Dispatchers.Main
だけはエラーになります。次で対応方法を見せます。
Dispatchers.Main
テスト対象。先程のは IO
を使ってましたが、今回は Main
を使ってます。
テストコード
Dispatchers.Main
を使った場合はそのままテストを実行すると以下のようなエラーメッセージが表示されます。
java.lang.IllegalStateException: Module with the Main dispatcher had failed to initialize. For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used
Dispatchers.Main
が初期化できないため、エラーになっています。エラーメッセージに対応方法が書いてあるので、それをやります。
kotlinx-coroutines-test
kotlinx-coroutines-test
を使います。
build.gradleに以下を追加します。
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.1.0'
Dispatchers.setMain
を使って Dispatchers.Main
を別のDispatcherに置き換えます。
これでテストが通ります。
ちょっと分かってないこととしては、setMainに渡すDispatcherを Dispatchers.Default
にするとうまくテストが通らないことがありました。 Dispatchers.Unconfined
だとうまくいくのですが、呼び出し元のスレッドで実行されるからってことですかねぇ(自信ない)
まとめ
runBlocking
を使えばだいたい大丈夫な気がします。何かまた気づいたら書きます。