💭

Kotlin/JSでsuspend関数をテストする

2021/12/23に公開

Kotlin/JSでsuspend関数をテストする

Kotlin/JSではrunBlockingのようにsuspend(非同期)関数を同期関数に変換できる関数が使えない。JavaScriptのランタイムで実現できないためだ。そしてkotlin-testでは@Testアノテーションをsuspend関数に適用できない。

  // e:/path/to/source.kt: Unsupported [suspend test functions]
  @Test suspend fun foo() {
      ...
  }

その結果として、Kotlin/JSではsuspend関数がテストできなかった。これは割と大きな問題で、結局テストはKotlin/JVMでしか動かさない、みたいな状況に陥りがちだった。

この状況が、今日リリースされたkotlinx.coroutines 1.6.0のリリースで変わってくるかもしれない。kotlinx.coroutinesの目玉機能のひとつとしてトップバッターで紹介されているのがkotlinx-coroutines-testだ。

https://blog.jetbrains.com/kotlin/2021/12/introducing-kotlinx-coroutines-1-6-0/#kotlinx-coroutines-test-update

coroutines 1.6.0を使うと、新たにrunTest { ... }というブロックでsuspend関数を呼び出すことが可能になる。テストの実行は投げっぱなしにならず同期的に終了してくれる。

  @Test fun foo() = runTest {
     ...
  }

runTest()にはdispatchTimeoutMs引数でタイムアウトも指定できるので、テスト対象ブロックがきちんと終了しない場合にも中断できるし、context引数でCoroutineContextを渡すこともできる。

これで、これまでjvmTest { ... }にしか置けなかったテストがcommonTest { ... }にも置けるようになるので、Multiplatformプロジェクトを作っている人は積極的に使っていくといいと思う。

Discussion