SpringBoot单元测试(二)MockMVC

介绍

MockMvc,从字面来理解,很好理解,主要是用来模拟MVC。简单来说,就是模拟可以从客户端请求后端的Controller类。

样例:

1. 非自动注入式

TestApplicationTests类已经有@RunWith(SpringRunner.class)和@SpringBootTest注解了,具体参考上一篇文章

SpringBoot 单元测试(一)SpringBootTest

package com.orjrs.spring.test.unit;

import com.orjrs.spring.test.TestApplicationTests;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

/**
 * MockMvcTest
 *
 * @author orjrs
 * @date 2018-10-06 20:15
 */
@WebAppConfiguration // 1
public class MockMvcTest extends TestApplicationTests {
    @Autowired
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before // @Test注解的方法运行前执行,MockMvcBuilder构造MockMvc实例
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void post() throws Exception {
        String name = "Smart LIU";
        String msg = "您好";
        mockMvc.perform(
                MockMvcRequestBuilders.post("/unit/sayHello/" + name + "/" + msg)
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                //.content()
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                //.andExpect(MockMvcResultMatchers.content().contentType("text/plain;charset=UTF-8"))
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
    }
}

2. 自动注入
package com.orjrs.spring.test.unit;

import com.orjrs.spring.test.TestApplicationTests;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

/**
 * MockMvcTest
 *
 * @author orjrs
 * @date 2018-10-21 16:12
 */
@WebAppConfiguration // 1
@AutoConfigureMockMvc // 开启MockMvc自动注解
public class AutoMockMvcTest extends TestApplicationTests {
    // @Autowired
    // private WebApplicationContext webApplicationContext;

    @Autowired
    private MockMvc mockMvc;

    /*@Before // @Test注解的方法运行前执行,MockMvcBuilder构造MockMvc实例
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }*/

    @Test
    public void post() throws Exception {
        String name = "Smart LIU";
        String msg = "您好";
        mockMvc.perform(
                MockMvcRequestBuilders.post("/unit/sayHello/" + name + "/" + msg)
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                //.content()
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                //.andExpect(MockMvcResultMatchers.content().contentType("text/plain;charset=UTF-8"))
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
    }
}

源码分析:

MockMvcBuilders: 主要是用来构造MockMvc的。它有两个方法,如下:

public class MockMvcBuilders {
    public MockMvcBuilders() {
    }
    // 通过指定WebApplicationContext,根据上下文获取相应的Controller来构建MockMvc
    public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context) {
        return new DefaultMockMvcBuilder(context);
    }
    // 通过参数直接指定一组控制器来构建MockMVC
    public static StandaloneMockMvcBuilder standaloneSetup(Object... controllers) {
        return new StandaloneMockMvcBuilder(controllers);
    }
}

AbstractMockMvcBuilder还实现了ConfigurableMockMvcBuilder接口,即有以下方法

package org.springframework.test.web.servlet.setup;

import javax.servlet.Filter;
import org.springframework.test.web.servlet.MockMvcBuilder;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultHandler;
import org.springframework.test.web.servlet.ResultMatcher;

public interface ConfigurableMockMvcBuilder> extends MockMvcBuilder {
     T addFilters(Filter... var1);// 添加过滤器

     T addFilter(Filter var1, String... var2);// 添加过滤器

     T defaultRequest(RequestBuilder var1);//默认的RequestBuilder,每次执行时会合并到自定义的RequestBuilder中,即提供公共请求数据的;

     T alwaysExpect(ResultMatcher var1); // 定义全局的结果验证器,即每次执行请求时都进行验证的规则;

     T alwaysDo(ResultHandler var1);// 定义全局结果处理器,即每次请求时都进行结果处理;

     T dispatchOptions(boolean var1); // DispatcherServlet是否分发OPTIONS请求方法到控制器;

     T apply(MockMvcConfigurer var1);
}
public interface MockMvcBuilder {
    MockMvc build();
}

StandaloneMockMvcBuilder除了继承AbstractMockMvcBuilder之外,自己还提供了许多方法,这里不多说了。

MockMvc:
mockMvc.perform(
                MockMvcRequestBuilders.post("/unit/sayHello/" + name + "/" + msg)
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                //.content()
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                //.andExpect(MockMvcResultMatchers.content().contentType("text/plain;charset=UTF-8"))
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
    }

perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理,返回ResultActions类;

andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;

andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台;

andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理;

另外还提供了以下API:

setDefaultRequest:设置默认的RequestBuilder,用于在每次perform执行相应的RequestBuilder时自动把该默认的RequestBuilder合并到perform的RequestBuilder中;

setGlobalResultMatchers:设置全局的预期结果验证规则,如我们通过MockMvc测试多个控制器时,假设它们都想验证某个规则时,就可以使用这个;

setGlobalResultHandlers:设置全局的ResultHandler结果处理器;

RequestBuilder/MockMvcRequestBuilders

Request请求,有put、get、post、delete、patch、options、head、request、multipart、fileUpload、asyncDispatch请求方法。

MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder

主要是针对请求头的。有header、contentType、cookie、characterEncoding、requestAttr、sessionAttr、contextPath等方法

你可能感兴趣的:(Spring,IT)