MockMvc单元测试
一、简介
为何使用MockMvc?
对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等,所以为了可以对Controller进行测试,我们引入了MockMVC。
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
二、测试逻辑
- MockMvcBuilder构造MockMvc的构造器
- mockMvc调用perform,执行一个RequestBuilder请求,调用controller的业务处理逻辑
- perform返回ResultActions,返回操作结果,通过ResultActions,提供了统一的验证方式
- 使用StatusResultMatchers对请求结果进行验证
- 使用ContentResultMatchers对请求返回的内容进行验
-
整个测试过程非常有规律:
1、准备测试环境
2、通过MockMvc执行请求
3.1、添加验证断言
3.2、添加结果处理器
3.3、得到MvcResult进行自定义断言/进行下一步的异步请求
4、卸载测试环境
三、测试用例
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({"classpath:applicationContext.xml"})
@PropertySource("classpath:application.properties")
public class ControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
//该方法在每个方法执行之前都会执行一遍
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build();
}
@Test
public void longRentDetails() throws Exception {
String responseString = mockMvc.perform(
MockMvcRequestBuilders.get("/longRentDetails") //请求的url,请求的方法是get
.contentType(MediaType.APPLICATION_JSON)//发送数据的格式
.param("applyNo", "1536315") //添加参数(可以添加多个)
.param("batchNo", "153631515780") //添加参数(可以添加多个)
)
.andExpect(status().isOk()) //返回的状态是200
.andDo(print()) //打印出请求和相应的内容
.andReturn().getResponse().getContentAsString(); //将相应的数据转换为字符串
System.out.println("-----返回的json = " + responseString);
}
}
四、注解以及方法说明
MockMvcBuilder
MockMvc是spring测试下的一个非常好用的类,他们的初始化需要在setUp中进行。
MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,前者继承了后者。
① MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc;
② MockMvcBuilders.standaloneSetup(Object... controllers):通过参数指定一组控制器,这样就不需要从上下文获取了,比如this.mockMvc = MockMvcBuilders.standaloneSetup(this.controller).build();
这些Builder还提供了其他api,可以查看官方文档
MockMvcRequestBuilders
从名字可以看出,RequestBuilder用来构建请求的,其提供了一个方法buildRequest(ServletContext servletContext)用于构建MockHttpServletRequest;其主要有两个子类MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(如文件上传使用),即用来Mock客户端请求需要的所有数据。
主要API:
- MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根据uri模板和uri变量值得到一个GET请求方式的RequestBuilder,如果在controller的方法中method选择的是RequestMethod.GET,那在controllerTest中对应就要使用MockMvcRequestBuilders.get。
- post(String urlTemplate, Object... urlVariables):同get类似,但是是POST方法;
- put(String urlTemplate, Object... urlVariables):同get类似,但是是PUT方法;
- delete(String urlTemplate, Object... urlVariables) :同get类似,但是是DELETE方法;
- options(String urlTemplate, Object... urlVariables):同get类似,但是是OPTIONS方法;
ResultActions
调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,对ResultActions有以下三种处理:
- ResultActions.andExpect:添加执行完成后的断言。添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;
- ResultActions.andDo:添加一个结果处理器,比如此处使用.andDo(MockMvcResultHandlers.print())输出整个响应结果信息,可以在调试的时候使用。(备注)
- ResultActions.andReturn:表示执行完成后返回相应的结果
备注:
ResultHandler用于对处理的结果进行相应处理的,比如输出整个请求/响应等信息方便调试,Spring mvc测试框架提供了MockMvcResultHandlers静态工厂方法,该工厂提供了ResultHandler print()返回一个输出MvcResult详细信息到控制台的ResultHandler实现。
ResultMatchers
ResultMatcher用来匹配执行完请求后的结果验证,其就一个match(MvcResult result)断言方法,如果匹配失败将抛出相应的异常,spring mvc测试框架提供了很多***ResultMatchers来满足测试需求。
具体请百度。
MvcResult
即执行完控制器后得到的整个结果,并不仅仅是返回值,其包含了测试时需要的所有信息。
- MockHttpServletRequest getRequest():得到执行的请求;
- MockHttpServletResponse getResponse():得到执行后的响应;
- Object getHandler():得到执行的处理器,一般就是控制器;
- HandlerInterceptor[] getInterceptors():得到对处理器进行拦截的拦截器;
- ModelAndView getModelAndView():得到执行后的ModelAndView;
- Exception getResolvedException():得到HandlerExceptionResolver解析后的异常;
- FlashMap getFlashMap():得到FlashMap;
- Object getAsyncResult()/Object getAsyncResult(long timeout):得到异步执行的结果;
推荐阅读
-
Java学习记录:纠错Junit单元测试遇到的initializationerror:method initializationerror not found
-
使用junit进行单元测试时报错Invalid bound statement (not found)
-
initializationError 单元测试错误
-
IDEA 单元测试报错:Class not found:xxxx springboot
-
PHP单元测试利器:PHPUnit深入理解(1)_PHP教程
-
java单元测试JUnit框架原理与用法实例教程
-
浅谈maven单元测试设置代理
-
Spring 异常单元测试的解决
-
Android应用开发中单元测试分析
-
Spring 异常单元测试的解决