使用 JUnit5 assertThrows 和 MockWebServer 测试挂起函数的异常
Testing suspending functions for exception with JUnit5 assertThrows and MockWebServer
我们如何使用 MockWebServer 测试一个应该抛出异常的挂起函数?
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")
}
无法直接在 assertThrows
中调用 postApi.getPosts()
,因为它不是暂停函数,我尝试使用 async
、launch
和
val exception = testCoroutineScope.async {
assertThrows<RuntimeException> {
launch {
postApi.getPosts()
}
}
}.await()
但测试失败,每个变体 org.opentest4j.AssertionFailedError: Expected java.lang.RuntimeException to be thrown, but nothing was thrown.
。
您可以使用如下方式删除 assertThrows:
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")
}
fun `Given Server down, should return 500 error`()= testCoroutineScope.runBlockingTest {
// GIVEN
mockWebServer.enqueue(MockResponse().setResponseCode(500))
// WHEN
val result = runCatching {
postApi.getPosts()
}.onFailure {
assertThat(it).isInstanceOf(###TYPE###::class.java)
}
// THEN
assertThat(result.isFailure).isTrue()
Truth.assertThat(exception?.message)
.isEqualTo("com.jakewharton.retrofit2.adapter.rxjava2.HttpException: HTTP 500 Server Error")
}
这是最容易理解的例子
fun testDividePositiveNumZero(){
var throwing = ThrowingRunnable { Calculator().divide(1,0) }
assertThrows(IllegalArgumentException::class.java, throwing)
}
我们如何使用 MockWebServer 测试一个应该抛出异常的挂起函数?
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")
}
无法直接在 assertThrows
中调用 postApi.getPosts()
,因为它不是暂停函数,我尝试使用 async
、launch
和
val exception = testCoroutineScope.async {
assertThrows<RuntimeException> {
launch {
postApi.getPosts()
}
}
}.await()
但测试失败,每个变体 org.opentest4j.AssertionFailedError: Expected java.lang.RuntimeException to be thrown, but nothing was thrown.
。
您可以使用如下方式删除 assertThrows:
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")
}
fun `Given Server down, should return 500 error`()= testCoroutineScope.runBlockingTest {
// GIVEN
mockWebServer.enqueue(MockResponse().setResponseCode(500))
// WHEN
val result = runCatching {
postApi.getPosts()
}.onFailure {
assertThat(it).isInstanceOf(###TYPE###::class.java)
}
// THEN
assertThat(result.isFailure).isTrue()
Truth.assertThat(exception?.message)
.isEqualTo("com.jakewharton.retrofit2.adapter.rxjava2.HttpException: HTTP 500 Server Error")
}
这是最容易理解的例子
fun testDividePositiveNumZero(){
var throwing = ThrowingRunnable { Calculator().divide(1,0) }
assertThrows(IllegalArgumentException::class.java, throwing)
}