jeudi 27 juin 2019

How to write unit tests for asynchronous function with a callback argument

I'm writing common tests for my kotlin multiplatform library which implements the API business logic using ktor client library.

I have a function which takes a callback as an argument, use coroutines to make the request to the API, and then execute the callback.

Here is a simplified version of the function from my UserApi class I want to test

fun <T : Any> fetch(
    requestBuilder: HttpRequestBuilder,
    deserializer: DeserializationStrategy<T>,
    callback: (Either<ErrorMessage, T>) -> Unit)
{
    GlobalScope.launch(dispatcherIO) {
        val result: Either<ErrorMessage, T> =
        try {
            val returnObject: T = Json.parse(
                deserializer, 
                HttpClient().post(requestBuilder)
            )
            Either.Right(returnObject)
        } catch (e: Exception) {
            Either.Left(ErrorMessage(e.message))
        }
        withContext(dispatcherMain) { callback(result) }
    }
}

I would like to write a unit test like that:

@Test
fun requestOK() {
    runTest { //runTest returns a platform specific runBlocking
        val UserApi().fetch(request, User.serializer()) {
            it.fold(
                { failure -> fail("must return success" },
                { user -> assertEquals(expectedUser, user) }
            )
        }
    }    
}

Aucun commentaire:

Enregistrer un commentaire