0Pricing
Kotlin Academy · レッスン

コルーチンのテスト

suspend関数をテストします

「コルーチンのテスト」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。

コルーチンのテストが特別な理由

コルーチンは非同期に実行され、遅延を使用することがあります。テストには制御された時間と、suspend関数の完了を待つ手段が必要です。

kotlinx-coroutines-testライブラリは、まさにこの機能を提供します。

テストライブラリの追加

コルーチンのテストアーティファクトをテスト用の依存関係に追加します。

dependencies {
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1")
}

runTest

runTestがエントリーポイントです。コルーチンのテスト本体を実行し、すべての子コルーチンが完了するまで自動的に待機します。

import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test

class FetchTest {
    @Test
    fun fetches() = runTest {
        // suspend calls allowed here
    }
}

仮想時間

runTest内では、仮想時間を使ってdelayの呼び出しをスキップします。10秒の遅延も、実行順序を維持したまま即座に完了します。

import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest

// runTest {
//     delay(10_000) // returns immediately
// }

時間の手動操作

テストスケジューラーを使うと、advanceTimeByで時間を意図的に進めたり、runCurrentで保留中の処理を実行したりできます。

import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent

// runTest {
//     launch { delay(1000); println("done") }
//     advanceTimeBy(1000)
//     runCurrent()
// }

テスト用ディスパッチャー

StandardTestDispatcherは時間を進めるまでコルーチンをキューに入れます。UnconfinedTestDispatcherはコルーチンを即座に実行します。必要な制御の度合いに応じて選択してください。

import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.UnconfinedTestDispatcher

val standard = StandardTestDispatcher()
val unconfined = UnconfinedTestDispatcher()

ディスパッチャーの注入

本番コードでは、Dispatchers.IOを直接指定するのではなく、ディスパッチャーを受け取るようにします。そうすれば、テストではテスト用ディスパッチャーを注入できます。

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class Service(private val io: CoroutineDispatcher = Dispatchers.IO) {
    suspend fun load(): String = withContext(io) { "data" }
}

Dispatchers.Mainの置き換え

Android形式のコードでは、Dispatchers.setMain(testDispatcher)を使ってMainディスパッチャーを置き換え、後でリセットします。

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.test.setMain
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.StandardTestDispatcher

// Dispatchers.setMain(StandardTestDispatcher())
// ... test ...
// Dispatchers.resetMain()

Suspend関数のテスト

runTest内では、suspend関数を直接呼び出してアサーションできます。

import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals

suspend fun compute(): Int { delay(1000); return 42 }

// @Test fun computes() = runTest {
//     assertEquals(42, compute())
// }

Flowのテスト

Flowを収集し、発行された値をアサーションします。Turbineライブラリを使うと、Flowのテストを特にすっきりと記述できます。

import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals

// @Test fun emits() = runTest {
//     val values = flowOf(1, 2, 3).toList()
//     assertEquals(listOf(1, 2, 3), values)
// }

実行可能なコルーチンスニペット

テストの外では、runBlockingがsuspendコードと通常のmainの橋渡しをします。これは、テスト対象のsuspend関数を示す例です。

import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.delay

suspend fun compute(): Int { delay(100); return 42 }

fun main() = runBlocking {
    println(compute())
}

簡単な確認

suspend関数がdelay(5000)を呼び出します。runTestを使ったテストがほぼ瞬時に終了するのはなぜでしょうか。

まとめ

コルーチンを確実にテストできるようになりました。

  • runTestはsuspendコードを実行し、子コルーチンを待機します
  • 仮想時間によって遅延をスキップします。必要に応じて手動で時間を進めます
  • ディスパッチャーを注入し、setMain/resetMainを使用します
  • Flowは収集してテストします(またはTurbineを使用します)

これでTestingコースは完了です。

よくある質問

「コルーチンのテスト」レッスンは無料ですか?

はい。「コルーチンのテスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。

「コルーチンのテスト」で何を学びますか?

suspend関数をテストします ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Kotlin Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「コルーチンのテスト」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このKotlin Academyレッスンでコードを書いて実行できますか?

はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. JUnit5でテストを書く
  2. アサーション
  3. MockKによるモック
  4. コルーチンのテスト
← Kotlin Academyに戻る