LoginSignup
5
3

More than 3 years have passed since last update.

Kotlin Coroutineのdelay()をユニットテストのときだけ待ち時間なしで実行する

Posted at

delay()を使ったコードのテストを実行すると、その設定時間だけ待たなきゃいけなくて辛いです。

class MyPrettyStopwatch(
    override val coroutineContext: CoroutineContext = Dispatchers.Default
) : CoroutineScope {

    var keikaByou: Int = 0
        private set

    private var job: Job? = null
    fun start() {
        stop()
        keikaByou = 0
        job = launch {
            while (true) {
                println("$keikaByou byou")
                delay(1000)
                keikaByou += 1
            }
        }
    }

    fun stop() {
        job?.cancel()
        job = null
    }
}
class MyPrettyStopwatchTest {
    @Test
    fun realtimeTest() {
        runBlocking {
            val stopwatch = MyPrettyStopwatch()
            stopwatch.start()
            delay(3100) // おっそ!
            Assert.assertEquals(3, stopwatch.keikaByou)
        }
    }
}

そんなときはTestCoroutineDispatcherを使います。

dependencies

build.gradle
dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
    testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.2.1'
}

TestCoroutineDispatcherkotlinx:kotlinx-coroutines-test1.2.1以降(2019/5/20現在の最新版)に入ってます。

使い方

class MyPrettyStopwatchTest {
    @ExperimentalCoroutinesApi
    @Test
    fun useTestCoroutineDispatcher(){
        val dispatcher = TestCoroutineDispatcher()
        val stopwatch = MyPrettyStopwatch(dispatcher)
        stopwatch.start()
        dispatcher.advanceTimeBy(3100) // すぐに実行されてえらい!
        Assert.assertEquals(3, stopwatch.keikaByou)
    }
}

その他

kotlinx-coroutines-testには他にもコルーチンのテストのためのユーティリティが揃ってます。

  • suspend関数をテストするのはrunBlockingTestが便利そう。
  • Dispatchers.setMain()Main dispatcherを切り替えられる。
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3