您的位置:

MockMvc:无需启动服务器的测试Spring mvc控制器的好工具

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时会提供更全面的控制器测试,这将更接近实际环境并有助于提升代码的稳定性。