MockMvc
1、概念MockMvc是服务端 Spring MVC测试支持的主入口点。可以用来模拟客户端请求,用于测试。2、API⑴ @RunWith注解指定测试运行器,例如使用 SpringJUnit4ClassRunner.class注意:如果使用的Spring的版本是4,则需要Servlet3的支持。如果引入了低版本的Servlet,则会报错:...
1、概念
MockMvc是服务端 Spring MVC测试支持的主入口点。可以用来模拟客户端请求,用于测试。
2、API
⑴ @RunWith注解
指定测试运行器,例如使用 SpringJUnit4ClassRunner.class
注意:如果使用的Spring的版本是4,则需要Servlet3的支持。
如果引入了低版本的Servlet,则会报错:
java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig
高版本Servlet Maven仓库链接
⑵ @ContextConfiguration注解
执行要加载的配置文件,例如 classpath:application.xml 或 file:src/main/resources/DispatcherServlet-servlet.xml
⑶ @WebAppConfiguration注解
用于声明测试时所加载的是WebApplicationContext【WebMVC的 XmlWebApplicationContext 是其实现类】
因为测试需要使用WebMVC对应的IOC容器对象
注意它需要结合 @ContextConfiguration注解 一起使用,否则报错:
java.lang.IllegalStateException: Failed to load ApplicationContext
⑷ WebApplicationContext
WebMVC的IOC容器对象,需要声明并通过@Autowired自动装配进来
⑸ MockMvcRequestBuilders
用于构建MockHttpServletRequestBuilder
① get GET请求
② post POST请求
③ put PUT请求
④ delete DELETE请求
⑤ param(String name, String… values) 传递参数 K-V…
⑹ MockHttpServletRequestBuilder
用于构建 MockHttpServletRequest,它用于作为 MockMvc的请求对象
⑺ MockMvc
通过 MockMvcBuilders 的 webAppContextSetup(WebApplicationContext context) 方法 获取 DefaultMockMvcBuilder,
再调用 build() 方法,初始化 MockMvc
① perform
perform(RequestBuilder requestBuilder) throws Exception
执行请求,需要传入 MockHttpServletRequest 对象【请求对象】
② andDo
andDo(ResultHandler handler) throws Exception
执行普通处理,例如 MockMvcResultHandlers的print() 方法用于 打印请求、响应及其他相关信息
③ andExpect
andExpect(ResultMatcher matcher) throws Exception
执行预期匹配,例如:
- MockMvcResultMatchers.status().isOk() 预期响应成功
- MockMvcResultMatchers.content().string(final String expectedContent) 指定预期的返回结果内容[字符串]
- MockMvcResultMatchers.content().contentType(String contentType) 指定预期的返回结果的媒体类型
- MockMvcResultMatchers.forwardedUrl(final String expectedUrl) 指定预期的请求的URL链接
- MockMvcResultMathcers.redirectedUrl(final String expectedUrl) 指定预期的重定向的URL链接
注意:当有一项不满足时,则后续就不会进行。
④ andReturn
andReturn()
返回 MvcResult [请求访问结果]对象
⑤ getRequest
getRequest()
返回 MockHttpServletRequest [请求]对象
⑻ MockHttpServletRequest
public class MockHttpServletRequest implements HttpServletRequest { }
请求对象
3、示例
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:application.xml", "file:src/main/resources/DispatcherServlet-servlet.xml"})
@WebAppConfiguration
// @Transactional 用于自动回滚操作
public class ???ControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before
public void initMockMvc() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void testGetUsers() {
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/???")
.param("???", "???")
.param("???", "???");
try {
MockHttpServletRequest request = mockMvc.perform(requestBuilder)
.andDo(MockMvcResultHandlers.print()) // 打印请求、响应及其他相关信息
.andExpect(MockMvcResultMatchers.status().isOk()) // 期待返回的状态是OK【200】
.andExpect(MockMvcResultMatchers.content().string("hello")) // 期待返回的内容是“hello”
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_VALUE)) // 预期返回的媒体类型是JSON
.andExpect(MockMvcResultMatchers.forwardedUrl("/WEB-INF/views/result.jsp")) // 预期请求到此页面
.andReturn()
.getRequest();
// 拿到了请求对象。。。
} catch (Exception e) {
e.printStackTrace();
}
}
}
Tips:
可以在测试类上,添加 @Transactional 注解,用于自动回滚操作
添加此注解后,在执行完业务操作后,通过日志可以查看回滚操作:
DEBUG org.springframework.test.context.transaction.TransactionalTestExecutionListener.isRollback(TransactionalTestExecutionListener.java:429) No method-level @Rollback override: using default rollback [true] for test context [DefaultTestContext@???????? testClass = ???, testInstance = ???@????????, testMethod = ???@???, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@???????? testClass = ???, locations = '{???.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
DEBUG org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization.beforeCompletion(SqlSessionUtils.java:310) Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@????????]
DEBUG org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization.beforeCompletion(SqlSessionUtils.java:315) Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@????????]
DEBUG org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:847) Initiating transaction rollback
DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager.doRollback(DataSourceTransactionManager.java:281) Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@???????? [wrapping: com.mysql.jdbc.JDBC4Connection@????????]]
DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager.doCleanupAfterCompletion(DataSourceTransactionManager.java:324) Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@???????? [wrapping: com.mysql.jdbc.JDBC4Connection@????????]] after transaction
DEBUG org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:327) Returning JDBC Connection to DataSource
INFO org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:298) Rolled back transaction after test execution for test context [DefaultTestContext@???????? testClass = ???, testInstance = ???@????????, testMethod = ???@???, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@???????? testClass = ???, locations = '{???.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
- 准备回滚操作
- 事务同步注销SqlSession
- 事务同步关闭SqlSession
- 初始化事务回滚操作
- 回滚对应的JDBC连接的事务操作
- 释放JDBC连接
- 将JDBC连接放回数据源连接池中
- 结束事务操作
更多推荐
所有评论(0)