2017-11-08 12 views
13

私はdelay()を使用するKotlinコルーチンを単体テストしようとしています。単体テストの場合、私はdelay()を気にしません。テストを遅くするだけです。私はdelay()が呼び出されたときに実際には遅延しない何らかの方法でテストを実行したいと思います。単位を遅くしてKotlinコルーチンをテストする

私はCommonPoolに委任するカスタムコンテキストを使用してコルーチンを実行してみました:

class TestUiContext : CoroutineDispatcher(), Delay { 
    suspend override fun delay(time: Long, unit: TimeUnit) { 
     // I'd like it to call this 
    } 

    override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) { 
     // but instead it calls this 
    } 

    override fun dispatch(context: CoroutineContext, block: Runnable) { 
     CommonPool.dispatch(context, block) 
    } 
} 

「私は、私はちょうど私のコンテキストのdelay()メソッドから返すことができます願っていたが、その代わりに、それは私のscheduleResumeAfterDelay()メソッドを呼び出している、と私はドンそれをデフォルトスケジューラに委譲する方法を知っています。 delay()は、遅延なしで再開される方法

+0

遅延タイムアウトを設定して、テストで非常に小さいものを選択できるようにすることはできませんか? – s1m0nw1

+0

@ s1m0nw1はい、私はむしろ一般的な解決策を持っていて、そのようなコードを変更する必要はありません。 –

+0

@eoinmullan、あなたは同じもののための最小のgitプロジェクトを共有できますか? –

答えて

7

あなたが任意の遅延をしたくない場合は、なぜあなたは、単にスケジュールコールで継続を再開していない?:

class TestUiContext : CoroutineDispatcher(), Delay { 
    override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) { 
     continuation.resume(Unit) 
    } 

    override fun dispatch(context: CoroutineContext, block: Runnable) { 
     //CommonPool.dispatch(context, block) // dispatch on CommonPool 
     block.run() // dispatch on calling thread 
    } 
} 

start 
launched 
stop 

EDIT:

を制御できます(yield()のような)

@Test 
fun `test with delay`() { 
    runBlocking(TestUiContext()) { 
     launch { println("launched") } 
     println("start") 
     delay(5000) 
     println("stop") 
    } 
} 

遅滞なく実行され、印刷物、これはまだ遅れで中断していることに注意してくださいので、他のコルーチンはまだ実行することができます継続はdispatch機能をカスタマイズすることによって実行されます。

+0

そして、 'dispatch()'は 'block.run()'だけでもかまいません。これはメインスレッドで実行を続けます。 –

+0

True、それはCommonPoolの使用を望んでいたようですが、テストには意味があるかもしれません。 – bj0

+0

私はOPです、むしろ同じスレッドを使用したいと思います。変更を加えれば、私はあなたの答えを受け入れるでしょう。 –

関連する問題