参考文档:SpringBoot基础之MockMvc单元测试

1. 简介

MockMvc 是由 spring-test 包提供,实现了对 Http 请求的模拟,能够直接使用网络的形式,转换到 Controller 的调用,使得测试速度快、不依赖网络环境。同时提供了一套验证的工具,结果的验证十分方便。

接口 MockMvcBuilder,提供一个唯一的 build 方法,用来构造 MockMvc。主要有两个实现:StandaloneMockMvcBuilder 和DefaultMockMvcBuilder,分别对应两种测试方式,即独立安装和集成Web环境测试(并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)。

MockMvcBuilders 提供了对应的创建方法 standaloneSetup 方法和 webAppContextSetup 方法,在使用时直接调用即可。

2. 使用

jar 包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
@SpringBootTest
class ProxyControllerTest {

    private MockMvc mvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @BeforeEach
    void setUp() {
        // 方式一
        mvc = MockMvcBuilders.standaloneSetup(new ProxyController(new ProxyUrlServiceImpl())).build();
        // 方式二
        mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    void proxyNodeInfo() throws Exception {
        RequestBuilder request = MockMvcRequestBuilders.get(URI.create("/proxy/info?target=clash"));
        mvc.perform(request).andExpect(status().is3xxRedirection());
    }
}
@Test
public void testHello() throws Exception {
    /*
     * 1、mockMvc.perform执行一个请求。
     * 2、MockMvcRequestBuilders.get("XXX")构造一个请求。
     * 3、ResultActions.param添加请求传值
     * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型
     * 5、ResultActions.andExpect添加执行完成后的断言。
     * 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情
     *   比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
     * 7、ResultActions.andReturn表示执行完成后返回相应的结果。
     */
    mockMvc.perform(MockMvcRequestBuilders
            .get("/hello")
            // 设置返回值类型为utf-8,否则默认为ISO-8859-1
            .accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
            .param("name", "Tom"))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andExpect(MockMvcResultMatchers.content().string("Hello Tom!"))
            .andDo(MockMvcResultHandlers.print());
}