
Spring Boot 3.4 中我发现非常重要的下一个特性是通过引入一个全新的测试类 MockMvcTester 来支持 AssertJ 进行 MockMvc 测试。在本文中,我们想深入探讨 Spring Boot 3.4 中的这一新特性,看看它如何帮助我们的 MockMvc 测试并提高测试的可读性。
我为这篇文章编写了一个非常基础的 Spring MVC 控制器,带有一个 /hello 端点:
@RestController
@SpringBootApplication
public class DemoMockmvcApplication {
public static void main(String[] args) {
SpringApplication.run(DemoMockmvcApplication.class, args);
}
@GetMapping("hello")
public String hello(){
return "Hello Spring!";
}
}通过这种方式,Spring 开发者通常选择
AssertJ来编写测试中的断言,但对于测试 Spring MVC 控制器中的断言,我们必须使用Hamcrest匹配器!
@SpringBootTest
@AutoConfigureMockMvc
class DemoMockmvcApplicationTests {
@Autowired
private MockMvc mockMvc;
@Test
void helloEndpoint_shouldReturnHelloMessage_hamcrest() throws Exception {
this.mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("Hello Spring!")));
}
}或者使用 AssertJ 断言在 MockMvc 匹配器中:
@SpringBootTest
@AutoConfigureMockMvc
class DemoMockmvcApplicationTests {
@Autowired
private MockMvc mockMvc;
@Test
void helloEndpoint_shouldReturnHelloMessage_assertj() throws Exception {
this.mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(result -> assertThat(result.getResponse().getContentAsString())
.isEqualTo("Hello Spring!"));
}
}MockMvcTester 是如何工作的?
从 Spring Boot 3.4 开始,为我们提供了一个自动配置的 MockMvcTester ,它允许我们使用 AssertJ 流畅的 API 定义请求和断言。 MockMvcTester 建立在普通的 MockMvc 之上,并允许我们构建请求并返回一个与 AssertJ 兼容的结果,以便可以将其包装在标准的 assertThat() 方法中。
@SpringBootTest
@AutoConfigureMockMvc
class DemoMockmvcApplicationTests {
@Autowired
private MockMvcTester mockMvcTester;
@Test
void helloEndpoint_shouldReturnHelloMessage_mockMvcTester() {
mockMvcTester.get().uri("/hello").assertThat() //or - assertThat(mockMvcTester.get().uri("/hello"))
.hasStatusOk()
.bodyText().isEqualTo("Hello Spring!");
}
}使用 MockMvcTester 相较于 MockMvc 的优势
MockMvcTester 是围绕 MockMvc 构建的,但它有几个优势:
- 无需为
AssertJ断言使用静态导入,因为请求和断言都可以使用流畅的 API 来构建。 - 未解决的异常会得到一致处理,因此您的测试不需要抛出(或捕获)
Exception(我们需要为MockMvc处理它) - 默认情况下,无论处理是异步还是同步,断言的结果都是完整的。换句话说,不需要以特殊方式处理异步请求。
- 除了 MockMvcTester 的 AssertJ 断言外,还有几种方法可以在原始的
MockMvcAPI 中集成MockMvcTester与MockMvc(了解更多方法请点击此处)。
总结
Spring Boot 3.4 中 AssertJ 与 MockMvc 的集成为偏好 AssertJ 而非其他替代方案的 Spring 开发者提供了一种统一编写测试的重要进步。通过 AssertJ 提供的流畅且富有表现力的断言,控制器测试用例的可读性和可维护性将得到提升。