2017-11-08 5 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() 방법을 부르고, 나는 '돈 기본 스케줄러에 위임하는 방법을 알고 있습니다.

+0

지연 시간 제한을 구성 할 수 없으므로 테스트에서 매우 작은 것을 선택할 수 있습니까?! – s1m0nw1

+0

@ s1m0nw1 예,하지만 일반적인 솔루션을 사용하고 코드를 수정하지 않아도됩니다. –

+0

@eoinmullan, 같은 git 프로젝트를 공유 할 수 있습니까? –

답변

7

당신이 어떤 지연을 원하지 않는 경우, 당신은 왜 단순히 일정 호출에서 계속? delay() 더 지연이 다시 시작됩니다

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 

편집 :

을 제어 할 수 있습니다 (yield() 같은)

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

지체없이 실행하고 인쇄이 여전히 지연에 일시 중단합니다, 그래서 다른 코 루틴은 여전히 ​​실행할 수 있습니다 계속은 dispatch 기능을 사용자 정의하여 실행됩니다.

+0

그리고'dispatch()'는 단지'block.run()'일 수 있습니다. 이것은 메인 쓰레드에서 실행을 유지합니다. –

+0

사실, CommonPool을 사용하기를 원했을지라도 테스트를 위해서는 의미가 있습니다. – bj0

+0

나는 OP이고, 나는 같은 스레드를 사용하고 싶다. 변경을하면 답을 수락합니다. –