Как заставить runBlocking ждать «всех потоков» в модульном тестировании? - PullRequest
0 голосов
/ 20 апреля 2019

Я пытаюсь написать модульный тест для функции getUser():

fun getUser(userId:Int) {
    // some code...

    launchDataOperation { api.getUser(userId) }
}

Проблема, которую я вижу (но не знаю, как решить ее чисто), - launchDataOperation(...)создает сопрограмму для вызова функции приостановки api.getUser:

fun launchDataOperation(block: suspend () -> Unit): Job {
    return coroutineScope.launch {
        try {
            setLoading(true)
            block()
        } catch (error: NetworkConnectionException) {
            setError(Errors.NETWORK_CONNECTION_ERROR)
        } catch (error: DataOperationException) {
            setMessage(error.getErrors())
        } finally {
            setLoading(false)
        }
    }
}

Это мой неудачный тест:

@Test
fun `error message is displayed if api error occurred`() {
    val exception = DataOperationException(listOf("FATAL ERROR"))

    runBlocking {
        `when`(api.getUser(anyInt())).thenAnswer { throw exception }

        subject.getUser(userId)

        // execution fails if the below line is commented
        // this is not the correct way to wait for other coroutines
        delay(500)  // wait for 500ms till the other coroutines finish

        assertThat(subject.messages.value).isEqualTo(exception.getErrors())
    }
}
...