androidunit-testingkotlin-coroutinesmockwebserver

Testing suspending functions for exception with JUnit5 assertThrows and MockWebServer


How can we test a suspending function with MockWebServer that supposed to throw exception?

fun `Given Server down, should return 500 error`()= testCoroutineScope.runBlockingTest {

    // GIVEN
    mockWebServer.enqueue(MockResponse().setResponseCode(500))

    // WHEN
    val exception = assertThrows<RuntimeException> {
        testCoroutineScope.async {
            postApi.getPosts()
        }

    }

    // THEN
    Truth.assertThat(exception.message)
        .isEqualTo("com.jakewharton.retrofit2.adapter.rxjava2.HttpException: HTTP 500 Server Error")
}

Calling postApi.getPosts() directly inside assertThrows is not possible since it's not a suspending function, i tried using async, launch and

 val exception = testCoroutineScope.async {
            assertThrows<RuntimeException> {
                launch {
                    postApi.getPosts()
                }
            }
        }.await()

but test fails with org.opentest4j.AssertionFailedError: Expected java.lang.RuntimeException to be thrown, but nothing was thrown. for each variation.


Solution

  • You could just remove the assertThrows, using something like this:

    fun `Given Server down, should return 500 error`()= testCoroutineScope.runBlockingTest {
    
        // GIVEN
        mockWebServer.enqueue(MockResponse().setResponseCode(500))
    
        // WHEN
        val exception = try {
            postApi.getPosts()
            null
        } catch (exception: RuntimeException){
            exception
        }
    
        // THEN
        Truth.assertThat(exception?.message)
            .isEqualTo("com.jakewharton.retrofit2.adapter.rxjava2.HttpException: HTTP 500 Server Error")
    }