单元测试在执行过程中冻结
Unit test freezes during the execution
所以,我遇到了我的问题 - 我正在尝试为我的应用程序进行单元测试。我有 2 个服务,我们称它们为 Foo 和 Bar,而 Foo 只不过是 Bar 的代理。
因此,Foo 服务的路由器如下所示:
fun fooRoute(...) = coRouter {
. . .
GET("/something", fooHandler::findSomething)
. . .
}
向 Bar 服务发出请求的处理程序如下所示:
fun fooHandler(barClient: WebClient) {
. . .
suspend fun findSomething(request: ServerRequest): ServerResponse {
val response = barClient.get()
.uri(...)
.accept(...)
.awaitExchange()
. . .
return when (response.statusCode()) {
HttpStatus.OK -> {
ServerResponse
. . .
.bodyValueAndAwait(response.awaitBody<SomeType>())
}
else -> {
ServerResponse
. . .
.buildAndAwait()
}
}
}
. . .
}
当我这样写测试时:
. . .
private val barClient = mockk<WebClient>()
private val fooHandler = FooHandler(barClient)
private val fooRouter = FooRouter()
private val fooClient = WebTestClient.bindToRouterFunction(
fooRouter.fooRoute(
// mocks
. . .
fooHandler
)
).build()
@Nested
inner class FindSomething {
@Test
fun `returns OK`() = runBlocking {
val response = mockk<ClientResponse>()
val spec = mockk<WebClient.RequestHeadersUriSpec<*>>()
coEvery { response.awaitBody<SomeType>() } returns SomeType(...)
coEvery { spec.awaitExchange() } returns response
coEvery { barClient.get() } returns spec
fooClient
.get()
.uri(...)
.exchange()
.expectStatus().is2xxSuccessful
. . .
}
}
它永远冻结了......好吧,我认为这是因为它周围有一些协程魔法,但因为我在这方面还是新手,所以我不明白这里到底发生了什么。有帮助吗?
好吧,我根据 this 的回答编写了自己的交换函数,解决了这个问题。这是我如何做到这一点的一个例子:
. . .
fun setUpBarClient(exchangeFunction: ExchangeFunction) {
barClient = barClient.mutate()
.exchangeFunction(exchangeFunction)
.build()
// recreate fooHandler & fooClient
}
@Nested
inner class FindSomething {
@Test
fun `returns OK`() {
// this one from org.springframework.web.reactive.function.client.ExchangeFunction
val exchangeFunction = ExchangeFunction {
Mono.just(
ClientResponse.create(HttpStatus.OK)
.header(...)
.body(...)
.build()
)
}
setUpBarClient(exchangeFunction)
fooClient
.get()
.uri(...)
.exchange()
.expectStatus().is2xxSuccessful
. . .
}
}
所以,我遇到了我的问题 - 我正在尝试为我的应用程序进行单元测试。我有 2 个服务,我们称它们为 Foo 和 Bar,而 Foo 只不过是 Bar 的代理。
因此,Foo 服务的路由器如下所示:
fun fooRoute(...) = coRouter {
. . .
GET("/something", fooHandler::findSomething)
. . .
}
向 Bar 服务发出请求的处理程序如下所示:
fun fooHandler(barClient: WebClient) {
. . .
suspend fun findSomething(request: ServerRequest): ServerResponse {
val response = barClient.get()
.uri(...)
.accept(...)
.awaitExchange()
. . .
return when (response.statusCode()) {
HttpStatus.OK -> {
ServerResponse
. . .
.bodyValueAndAwait(response.awaitBody<SomeType>())
}
else -> {
ServerResponse
. . .
.buildAndAwait()
}
}
}
. . .
}
当我这样写测试时:
. . .
private val barClient = mockk<WebClient>()
private val fooHandler = FooHandler(barClient)
private val fooRouter = FooRouter()
private val fooClient = WebTestClient.bindToRouterFunction(
fooRouter.fooRoute(
// mocks
. . .
fooHandler
)
).build()
@Nested
inner class FindSomething {
@Test
fun `returns OK`() = runBlocking {
val response = mockk<ClientResponse>()
val spec = mockk<WebClient.RequestHeadersUriSpec<*>>()
coEvery { response.awaitBody<SomeType>() } returns SomeType(...)
coEvery { spec.awaitExchange() } returns response
coEvery { barClient.get() } returns spec
fooClient
.get()
.uri(...)
.exchange()
.expectStatus().is2xxSuccessful
. . .
}
}
它永远冻结了......好吧,我认为这是因为它周围有一些协程魔法,但因为我在这方面还是新手,所以我不明白这里到底发生了什么。有帮助吗?
好吧,我根据 this 的回答编写了自己的交换函数,解决了这个问题。这是我如何做到这一点的一个例子:
. . .
fun setUpBarClient(exchangeFunction: ExchangeFunction) {
barClient = barClient.mutate()
.exchangeFunction(exchangeFunction)
.build()
// recreate fooHandler & fooClient
}
@Nested
inner class FindSomething {
@Test
fun `returns OK`() {
// this one from org.springframework.web.reactive.function.client.ExchangeFunction
val exchangeFunction = ExchangeFunction {
Mono.just(
ClientResponse.create(HttpStatus.OK)
.header(...)
.body(...)
.build()
)
}
setUpBarClient(exchangeFunction)
fooClient
.get()
.uri(...)
.exchange()
.expectStatus().is2xxSuccessful
. . .
}
}