MockMvc是Spring测试框架的一部分,它是一种对Spring Mvc web应用程序的模拟测试框架。MockMvc是在不启动Web服务器的情况下进行测试的好工具,使用MockMvc你可以获得MVC-风格的控制器的完整行为,从而更好地测量控制器处理HTTP请求的能力。
一、MockMvc.perform
使用MockMvc来测试Spring Mvc控制器,你可以使用MockMvc.perform方法,该方法允许你执行MockMvcRequestBuilders和MockMvcResultMatchers。MockMvcRequestBuilders是用于构建HTTP请求的静态工厂,MockMvcResultMatchers是用于检查请求响应的静态工厂。
mockMvc.perform(MockMvcRequestBuilders.get("/users")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("hello world"));
这里,我们使用MockMvc来执行HTTP GET请求并验证响应代码是否为200,响应页面是否与给定的内容相同。
二、mockMvc如何模拟http的post方法
与执行HTTP GET请求相比,MockMvc还可以使用MockMvcRequestBuilders来构建其他HTTP请求方法,例如POST、PUT、DELETE和PATCH。特别是对于HTTP POST请求而言,我们需要提供请求参数和请求头。
mockMvc.perform(MockMvcRequestBuilders.post("/users") .param("name", "testUser") .header("X-Auth-Token", "tokenValue")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("success"));
三、mock
MockMvc执行HTTP请求时可能需要伪造一些对象。mock是一个Java库,它允许您在不使用实际服务的情况下测试代码。
@RunWith(MockitoJUnitRunner.class) public class TestUserController { @Mock private UserService userService; @InjectMocks private UserController userController; private MockMvc mockMvc; @Before public void setUp() { mockMvc = MockMvcBuilders.standaloneSetup(userController).build(); } @Test public void testGetUserById() throws Exception { User user = new User(); user.setId(1); user.setName("testUser"); Mockito.when(userService.getUserById(1)).thenReturn(user); mockMvc.perform(MockMvcRequestBuilders.get("/users/1")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.jsonPath("$.name").value(user.getName())); } }
这里,我们使用mockito来类似地实例化一个UserService并修改其行为。在这种情况下,我们没有真正启动服务器,而只是测试UserController是否正确处理HTTP GET请求。在一个真正的Spring Mvc环境中,这将提高你的开发效率,因为你可以对控制器进行测试无需启动任何服务器。
四、MockMvc body
MockMvc提供了RequestBodyBuilder,用于构建http请求的body部分。
mockMvc.perform(MockMvcRequestBuilders.post("/users") .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"testUser\"}")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("success"));
这里,我们使用RequestBodyBuilder构建了一个json格式的请求体,并将其传递给了MockMvc perform方法中的content()函数。
五、Spring Mock单元测试
MockMvc也可以使用Spring的Mock测试框架。使用@SpringBootTest和@AutoConfigureMockMvc注释,允许您在模拟的http servlet容器中测试Spring Mvc应用程序。这是一个更接近实际环境的模拟,可以提供更全面的控制器测试。
@SpringBootTest @AutoConfigureMockMvc public class TestUserController { @Autowired private MockMvc mockMvc; @MockBean private UserService userService; @Test public void testGetUserById() throws Exception { User user = new User(); user.setId(1); user.setName("testUser"); Mockito.when(userService.getUserById(1)).thenReturn(user); mockMvc.perform(MockMvcRequestBuilders.get("/users/1")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.jsonPath("$.name").value(user.getName())); } }
这里,我们使用@AutoConfigureMockMvc和@SpringBootTest对Spring MVC应用程序进行单元测试。由于我们使用了服务依赖注入,所以我们使用@MockBean来模拟UserService。
六、总结
MockMvc是一种非常有用的工具,在测试Spring Mvc控制器时可以提高开发效率。它提供模拟HTTP请求和测试期望结果的功能,并且可以使用Mockito对所需的对象进行伪造。在Spring模拟测试中使用MockMvc时会提供更全面的控制器测试,这将更接近实际环境并有助于提升代码的稳定性。