在面向对象程序设计中,模拟对象(mock object)是以可控的方式模拟真实对象行为的假的对象。比如:对象B依赖于对象A,但是A代码还没写,是一个空类,空方法不能用,我们来mock一个假的A来完成测试。
在单元测试中,模拟对象可以模拟复杂的、真实的对象的行为, 如果真实的对象无法放入单元测试中,使用模拟对象就很有帮助。
在下面的情形中,可能需要使用模拟对象来代替真实对象:
- 真实对象的行为是不确定的(例如,当前的时间或当前的温度);
- 真实对象很难搭建起来;
- 真实对象的行为很难触发(例如,网络错误);
- 真实对象速度很慢(例如,一个完整的数据库,在测试之前可能需要初始化);
- 真实的对象是用户界面,或包括用户界面在内;
- 真实的对象使用了回调机制;
- 真实对象可能还不存在(例如,其他程序员还为完成工作);
- 真实对象可能包含不能用作测试的信息(高度保密信息等)和方法。
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
因为在做系统的自动化持续集成的时候,会要求自动的做单元测试,只有所有的单元测试都跑通了,才能打包构建。比如:使用maven。这里重点是自动化,所以postman这种工具很难插入到持续集成的自动化流程中去。所以需要我们自己写代码完成单元测试。另外写代码测试能模拟出更多复杂的测试场景,类似Postman工具只能完成简单的接口测试。
原理:使用MockMvc发起请求,然后执行相应的代码,在执行的过程中使用Mockito的mock模拟底层数据的返回,最后结果验证。
相关API MockMvcBuildersMockMvcBuilders用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分别对应两种测试方式,即独立安装和集成Web环境测试(此种方式并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)。对于我们来说直接使用静态工厂MockMvcBuilders创建即可。
- public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context)
- MockHttpServletRequestBuilder get(String urlTemplate, Object… urlVariables) 根据uri模板和uri变量值得到一个GET请求方式的MockHttpServletRequestBuilder;如get(/user/{id}, 1L)
- MockHttpServletRequestBuilder post(String urlTemplate, Object… urlVariables) 同get类似,但是是POST方法
- MockHttpServletRequestBuilder put(String urlTemplate, Object… urlVariables) 同get类似,但是是PUT方法
- MockHttpServletRequestBuilder delete(String urlTemplate, Object… urlVariables) 同get类似,但是是DELETE方法
- MockHttpServletRequestBuilder options(String urlTemplate, Object… urlVariables) 同get类似,但是是OPTIONS方法
- MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, Object… urlVariables) 提供自己的Http请求方法及uri模板和uri变量,如上API都是委托给这个API
- MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object… urlVariables) 提供文件上传方式的请求,得到MockMultipartHttpServletRequestBuilder
- RequestBuilder asyncDispatch(final MvcResult mvcResult) 创建一个从启动异步处理的请求的MvcResult进行异步分派的RequestBuilder
MockMvcRequestBuilders通过方法得到两类Builder,一个是MockHttpServletRequestBuilder ,一个是MockMultipartHttpServletRequestBuilder (上传文件)
MockHttpServletRequestBuilder 主要有以下API:- MockHttpServletRequestBuilder header(String name, Object… values)/MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders) 添加头信息
- MockHttpServletRequestBuilder contentType(MediaType mediaType) 指定请求的contentType头信息
- MockHttpServletRequestBuilder accept(MediaType… mediaTypes)/MockHttpServletRequestBuilder accept(String… mediaTypes) 指定请求的Accept头信息;
- MockHttpServletRequestBuilder content(byte[] content)
- MockHttpServletRequestBuilder content(String content) 指定请求Body体内容;
- MockHttpServletRequestBuilder param(String name,String… values) 请求传入参数
- MockHttpServletRequestBuilder cookie(Cookie… cookies) 指定请求的Cookie
- MockHttpServletRequestBuilder locale(Locale locale) 指定请求的Locale
- MockHttpServletRequestBuilder characterEncoding(String encoding) 指定请求字符编码
- MockHttpServletRequestBuilder requestAttr(String name, Object value) 设置请求属性数据
- MockHttpServletRequestBuilder sessionAttr(String name, Object value)
- MockHttpServletRequestBuilder sessionAttrs(Map sessionAttributes) 设置请求session属性数据
- MockHttpServletRequestBuilder flashAttr(String name, Object value)
- MockHttpServletRequestBuilder flashAttrs(Map flashAttributes) 指定请求的flash信息,比如重定向后的属性信息
- MockHttpServletRequestBuilder session(MockHttpSession session) 指定请求的Session
- MockHttpServletRequestBuilder principal(Principal principal) 指定请求的Principal
- MockHttpServletRequestBuilder contextPath(String contextPath) 指定请求的上下文路径,必须以“/”开头,且不能以“/”结尾
- MockHttpServletRequestBuilder pathInfo(String pathInfo) 请求的路径信息,必须以“/”开头
- MockHttpServletRequestBuilder secure(boolean secure) 请求是否使用安全通道
- MockHttpServletRequestBuilder with(RequestPostProcessor postProcessor) 请求的后处理器,用于自定义一些请求处理的扩展点
MockMultipartHttpServletRequestBuilder继承自MockHttpServletRequestBuilder,提供了如下API:
- MockMultipartHttpServletRequestBuilder file(String name, byte[] content)
- MockMultipartHttpServletRequestBuilder file(MockMultipartFile file) 指定要上传的文件
调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,通过ResultActions可以完成如下三件事:
- ResultActions andExpect(ResultMatcher matcher) 添加验证断言,用来判断执行请求后的结果是否是预期的
- ResultActions andDo(ResultHandler handler) 添加结果处理器,用于设置验证成功后执行的动作,如输出下请求/结果信息用于调试
- MvcResult andReturn() 返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理
ResultMatcher用来匹配执行完请求后的结果验证,其就一个match(MvcResult result)断言方法,如果匹配失败将抛出相应的异常;具体提供以下API:
- HandlerResultMatchers handler() 请求的Handler验证器,比如验证处理器类型/方法名;此处的Handler其实就是处理请求的控制器
- RequestResultMatchers request() 得到RequestResultMatchers验证器
- ModelResultMatchers model() 得到模型验证器
- ViewResultMatchers view() 得到视图验证器
- FlashAttributeResultMatchers flash() 得到Flash属性验证
- StatusResultMatchers status() 得到响应状态验证器
- HeaderResultMatchers header() 得到响应Header验证器
- CookieResultMatchers cookie() 得到响应Cookie验证器
- ContentResultMatchers content() 得到响应内容验证器
- JsonPathResultMatchers jsonPath(String expression, Object … args)
- ResultMatcher jsonPath(String expression, Matcher matcher) 得到Json表达式验证器
- XpathResultMatchers xpath(String expression, Object… args)
- XpathResultMatchers xpath(String expression, Map namespaces, Object… args) 得到Xpath表达式验证器
- ResultMatcher forwardedUrl(final String expectedUrl) 验证处理完请求后转发的url(绝对匹配
- ResultMatcher forwardedUrlPattern(final String urlPattern) 验证处理完请求后转发的url(Ant风格模式匹配,@since spring4)
- ResultMatcher redirectedUrl(final String expectedUrl) 验证处理完请求后重定向的url(绝对匹配)
- ResultMatcher redirectedUrlPattern(final String expectedUrl) 验证处理完请求后重定向的url(Ant风格模式匹配,@since spring4)