如何正确测试含长耗时操作的WebFlux方法(无需Thread.sleep)
解决Spring WebFlux中Mono接口的同步操作结果验证问题
要实现无需Thread.sleep且验证内部同步操作结果的测试,核心思路是Mock依赖服务并捕获其调用结果,结合StepVerifier验证响应流的完成状态,同时断言Mock方法的返回值。具体步骤如下:
1. 准备Mock依赖
首先需要Mock掉someService实例,这样可以控制veryLongSyncOperation的返回值,并验证它是否被正确调用。可以用Spring的@MockBean或者Mockito的mock()方法来实现。
2. 编写测试用例
完整测试代码示例:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import reactor.test.StepVerifier; import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest public class FooControllerTest { @Autowired private FooController fooController; // 替换为你的接口所在实际类 @MockBean private SomeService someService; // 替换为你的实际服务类 @Test void bar_shouldExecuteSyncOperationAndReturnVoid() { // 1. 定义预期结果 String expectedResult = "expected_sync_result"; // 2. Mock同步方法的返回值 when(someService.veryLongSyncOperation()).thenReturn(expectedResult); // 3. 调用接口方法获取Mono<Void> Mono<Void> resultMono = fooController.bar(); // 4. 用StepVerifier验证流完成,无需Thread.sleep StepVerifier.create(resultMono) .verifyComplete(); // 验证Mono正常完成 // 5. 验证同步方法被调用,且结果符合预期 verify(someService, times(1)).veryLongSyncOperation(); // 直接断言返回值匹配预期 assertEquals(expectedResult, someService.veryLongSyncOperation()); } }
关键说明
- 无需Thread.sleep:
StepVerifier.create(resultMono).verifyComplete()会自动等待Reactor流完成,底层通过非阻塞方式处理异步操作,不需要手动休眠。 - 结果验证:通过Mock的
when()方法预设返回值,再结合verify()确认方法被调用次数,同时直接断言返回值符合预期,确保同步操作的执行结果正确。 - 线程调度处理:
subscribeOn(Schedulers.elastic())将同步操作切换到弹性线程池执行,StepVerifier会自动处理线程切换后的流等待,无需额外配置。
内容的提问来源于stack exchange,提问作者Aliaksei
相关产品推荐
相关产品推荐

