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'
}
TestCoroutineDispatcher
はkotlinx:kotlinx-coroutines-test
の1.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を切り替えられる。