You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对返回Mono类型的方法进行JUnit测试并获取响应体

问题原因

返回Mono类型的接口在Spring MVC中会触发异步Servlet处理流程,默认MockMvc的perform方法仅等待控制器方法执行完成,不会等待异步结果处理、写入响应体的全流程,因此你会看到响应体为空,目标值仅存在于Async异步结果中。

你额外添加的StepVerifier仅用于验证Service层Mono方法的返回值,和Controller层接口返回响应的流程无关,不会影响MockMvc的测试结果。

解决方案

调整MockMvc的调用逻辑,等待异步处理完成后再执行断言即可,修改后的测试代码如下:

@WebMvcTest(DataController.class)
public class DataMockTest {

  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private Service service;

  @Test
  public void getDataTest() throws Exception {
    Mono<String> strMono = Mono.just("Single Item Only");
    when(service.getData("DATA")).thenReturn(strMono);

    // 验证Service层返回
    StepVerifier.create(service.getData("DATA"))
        .assertNext(data -> {
          assertNotNull(data);
          assertEquals("Single Item Only", data);
        }).verifyComplete();

    // 第一步:执行请求,拿到异步结果
    MvcResult mvcResult = this.mockMvc.perform(get("/some/rest/toget/data")
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON))
        .andExpect(request().asyncStarted())
        .andReturn();
    // 阻塞等待异步处理完成,再执行分发写入响应
    this.mockMvc.perform(asyncDispatch(mvcResult))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(content().string("Single Item Only")); // 直接断言响应体内容
  }
}
可选优化方案

如果你的项目是Spring WebFlux全栈应用,更推荐使用@WebFluxTest搭配WebTestClient测试,无需手动处理异步逻辑,写法更简洁:

@WebFluxTest(DataController.class)
public class DataMockTest {

  @Autowired
  private WebTestClient webTestClient;

  @MockBean
  private Service service;

  @Test
  public void getDataTest() {
    Mono<String> strMono = Mono.just("Single Item Only");
    when(service.getData("DATA")).thenReturn(strMono);

    webTestClient.get().uri("/some/rest/toget/data")
        .accept(MediaType.APPLICATION_JSON)
        .exchange()
        .expectStatus().isOk()
        .expectBody(String.class)
        .isEqualTo("Single Item Only");
  }
}
注意事项

你原有代码中StepVerifier调用的service.getDATA("DATA")和mock的service.getData("DATA")大小写不一致,请确认方法名匹配,避免mock不生效的问题。


内容的提问来源于stack exchange,提问作者JayC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:36:00