SpringMvc框架MockMvc单元测试注解及其原理分析
首先简单介绍一下Spring,它是一个轻量级开源框架,简单的来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。特点方便解耦,简化开发,AOP编程的支持声明式,事务的支持以及降低Java EE API的使用难度等。
目前主流的Web MVC框架除了Struts之外就是SpringMVC,不过要想灵活运用SpringMVC来应对大多说的web开发除了必须掌握其配置和原理外还需要会测试。在Spring3.2版本之前测试一般都是直接new控制器注入依赖进行判断返回,但无法测试基础配置参数如拦截器、数据绑定、类型转换等等。
从Spring3.2版本之后这些都可以完成,并且是测试一个完成的SpringMVC流程。下面为大家分享一下SpringMVC框架中MockMvc注解含义及其原理分析。
SpringJunitTestMock测试类下各个注解/变量的含义如下:
1、下面对各变量/注解进行解释
@WebAppConfiguration
表明该类会使用web应用程序的默认根目录来载入ApplicationContext, 默认的更目录是"src/main/webapp", 如果需要更改这个更目录可以修改该注释的value值。
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration(value = "src/main/webapp")
@ContextHierarchy({
@ContextConfiguration(name = "parent" ,locations = "classpath:applicationContext.xml"),
})
@RunWith
使用 Spring-Test 框架;在使用所有注释前必须使用@RunWith(SpringJUnit4ClassRunner.class),让测试运行于Spring测试环境。
@ContextConfiguration(location = ): 指定需要加载的spring配置文件的地址
@Mock: 需要被Mock的对象
@Transactional:不是必须的,是和@TestExecutionListeners中的TransactionalTestExecutionListener.class配合使用,用于保证插入的数据库中的测试数据,在测试完后,事务回滚,将插入的数据给删除掉,保证数据库的干净。如果没有显示的指定@Transactional,那么插入到数据库中的数据就是真实数据。
@InjectMocks: 需要将Mock对象注入的对象, 此处就是Controller
@Before: 在每次Test方法之前运行的方法,目前把登陆信息放到session中处理,以及初始化mockMvc。
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
@Test:执行测试
基本框架,实例代码如下图:
参考资料:http://blog.yoodb.com/yoodb/article/detail/1321
2、具体测试的方法
测试方法中的mockMvc需要调用的方法:
1)mockMvc.perform执行一个请求(该请求由2构造);
2)MockMvcRequestBuilders.get("/user/1")构造一个请求
3)ResultActions.andExpect添加执行完成后的断言,目的测试返回结果,通过返回结果来确认测试是否成功
4)ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
5)ResultActions.andReturn表示执行完成后返回相应的结果。
mockMvc.perform(执行一个请求)
(MockMvcRequestBuilders.get("/order/one_orders") //构造一个请求
.session(session)
.contentType(MediaType.APPLICATION_XHTML_XML).param("page", "1"))
.andExpect(view().name("order/one_orders/index")) //执行完后写断言
3、整个测试过程非常有规律:
1)准备测试环境
2)通过MockMvc执行请求
3)添加验证断言
4)添加结果处理器
5)得到MvcResult进行自定义断言/进行下一步的异步请求
4、卸载测试环境
SpringMVC测试框架提供了两种方式,独立安装和集成Web环境测试
1、mockMvc.perform执行一个请求;
2、MockMvcRequestBuilders.get("/user/1")构造一个请求
3、ResultActions.andExpect添加执行完成后的断言
4、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
5、ResultActions.andReturn表示执行完成后返回相应的结果。
MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,StandaloneMockMvcBuilder继承了DefaultMockMvcBuilder。
直接使用静态工厂MockMvcBuilders创建即可:
MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc;
MockMvcBuilders.standaloneSetup(Object... controllers):通过参数指定一组控制器,这样就不需要从上下文获取了;
其中DefaultMockMvcBuilder还提供了如下API:
addFilters(Filter... filters)/addFilter(Filter filter, String... urlPatterns):添加javax.servlet.Filter过滤器
defaultRequest(RequestBuilder requestBuilder):默认的RequestBuilder,每次执行时会合并到自定义的RequestBuilder中,即提供公共请求数据的;
alwaysExpect(ResultMatcher resultMatcher):定义全局的结果验证器,即每次执行请求时都进行验证的规则;
alwaysDo(ResultHandler resultHandler):定义全局结果处理器,即每次请求时都进行结果处理;
dispatchOptions:DispatcherServlet是否分发OPTIONS请求方法到控制器;
StandaloneMockMvcBuilder继承了DefaultMockMvcBuilder,又提供了如下API:
setMessageConverters(HttpMessageConverter
setValidator(Validator validator):设置验证器;
setConversionService(FormattingConversionService conversionService):设置转换服务;
addInterceptors(HandlerInterceptor... interceptors)/addMappedInterceptors(String[] pathPatterns, HandlerInterceptor... interceptors):添加spring mvc拦截器;
setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager):设置内容协商管理器;
setAsyncRequestTimeout(long timeout):设置异步超时时间;
setCustomArgumentResolvers(HandlerMethodArgumentResolver... argumentResolvers):设置自定义控制器方法参数解析器;
setCustomReturnValueHandlers(HandlerMethodReturnValueHandler... handlers):设置自定义控制器方法返回值处理器;
setHandlerExceptionResolvers(List
setViewResolvers(ViewResolver...resolvers):设置视图解析器;
setSingleView(View view):设置单个视图,即视图解析时总是解析到这一个(仅适用于只有一个视图的情况);
setLocaleResolver(LocaleResolver localeResolver):设置Local解析器;
setFlashMapManager(FlashMapManager flashMapManager):设置FlashMapManager,如存储重定向数据;
setUseSuffixPatternMatch(boolean useSuffixPatternMatch):设置是否是后缀模式匹配,如“/user”是否匹配"/user.*",默认真即匹配;
setUseTrailingSlashPatternMatch(boolean useTrailingSlashPatternMatch):设置是否自动后缀路径模式匹配,如“/user”是否匹配“/user/”,默认真即匹配;
addPlaceHolderValue(String name, String value) :添加request mapping中的占位符替代;
StandaloneMockMvcBuilder不会加载Spring MVC配置文件,因此就不会注册我们需要的一些组件,因此就提供了如上API用于注册我们需要的相应组件。
perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;
andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;
andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台;
andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理;
MockMvcRequestBuilders主要API:
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方法;
调用MockMvc.perform(RequestBuilder requestBuilder)后,将得到ResultActions:
ResultActions andExpect(ResultMatcher matcher) :添加验证断言来判断执行请求后的结果是否是预期的;
ResultActions andDo(ResultHandler handler) :添加结果处理器,用于对验证成功后执行的动作,如输出下请求/结果信息用于调试;
MvcResult andReturn() :返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理。
优哉游哉
更多推荐:《优哉游哉》
号涵盖:程序人生、搞笑视频、算法与数据结构、黑客技术与网络安全、前端开发、Java、Python、Redis缓存、Spring源码、各大主流框架、Web开发、大数据技术、Storm、Hadoop、MapReduce、Spark、elasticsearch、单点登录统一认证、分布式框架、集群、安卓开发、iOS开发、C/C++、.NET、Linux、Mysql、Oracle、NoSQL非关系型数据库、运维等。