Spring WebFlux,单元测试 Mono 和 Flux

Posted

技术标签:

【中文标题】Spring WebFlux,单元测试 Mono 和 Flux【英文标题】:Spring WebFlux, unit testing Mono and Flux 【发布时间】:2019-01-20 15:51:44 【问题描述】:

对响应式编程很感兴趣,我玩过Building a Reactive RESTful Web Service 指南。并想向前推进并添加一些单元测试。

我尝试使用普通的 Junit/Mockito 测试来测试我的处理程序 (RouterFunction)。但是,因为它是反应式的,所以处理程序返回一个Mono<ServerResponse>。所以我不得不block()它来测试ServerResponse的状态,但无法提取他的身体来测试它。在网上搜索解决方案时,似乎所有示例都使用WebTestClient

我的问题是:

鉴于所有示例都使用 WebTestClient 来测试反应式 REST 服务,并且(单元)测试 ServerResponse 的主体并不容易。对RouterFunction 进行单元测试是一种好习惯,还是总是对WebTestClient 进行更广泛的测试更好?

非常感谢。

【问题讨论】:

有趣的问题。恐怕它最终可能主要是基于意见的,但由于我对 WebFlux 不是特别熟悉,这里可能有一个有用的最佳实践。 谢谢。当然,它将基于意见,但网络倾向于说除了使用WebTestClient 测试它之外没有其他干净的方法。所以要么我以错误的方式搜索,要么没有其他方式。 您阅读过 Project Reactor 参考的the testing section 吗? 是的。我的问题是(见答案)更多关于测试 ServerResponse 的主体 【参考方案1】:

似乎最好的做法是使用WebTestClient。然而,这个可以在没有运行服务器的情况下使用;

spring-test 模块包含一个 WebTestClient,可用于测试 WebFlux 服务器端点有或没有正在运行的服务器

-- https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html#web-reactive-tests

【讨论】:

请注意,它还不能很好地与 Kotlin 一起工作 (issue)【参考方案2】:

这取决于您要测试的具体内容,对于常规方法,您应该使用 StepVerifier 来消耗您测试的输出。但是 router 函数 是独一无二的,因为通常会返回一个 serverResponse 包含您的主体数据,所以在这种情况下最好使用 webClient 或 webTestClient。

【讨论】:

以上是关于Spring WebFlux,单元测试 Mono 和 Flux的主要内容,如果未能解决你的问题,请参考以下文章

Spring 5 WebFlux Mono 和 Flux

Spring Webflux:从 Mono 中提取价值

Spring webflux 反应式 Mono::subscribe

Log Spring webflux 类型 - Mono 和 Flux

Spring Webflux(Mono/Flux) 与 AOP 在拦截时触发 REST 调用并使用 Mono/Flux

如何在不阻塞的情况下从 Spring Webflux 中的 Mono 对象中提取数据?