SpringMVC框架如何与Junit整合看这个就够了
目录
- 系统环境
- 引入依赖
- 编写单元测试基类
- MockMvcRequestBuilders
- get请求测试
- post请求测试
- 文件上传测试
- 返回结果是视图请求的单元测试
- 直接测试一个service的方法
- 总结
系统环境
软件 | 版本 |
---|---|
spring-webmvc | 4.3.6.RELEASE |
spring-test | 4.3.6.RELEASE |
junit | 4.12 |
引入依赖
junit junit4.12 testorg.springframework spring-test${spring.version} test
如上,引入了4个依赖,其中:
- junit 是Junit单元测试的基础依赖,它提供了@RunWith和@Test等单元测试必备的注解。test 则指明了该依赖的作用范围是test阶段。
- spring-test依赖可以理解成是spring框架与junit框架的桥梁。提供了@WebAppConfiguration等注解。
编写单元测试基类
@RunWith(SpringJUnit4ClassRunner.class)@WebAppConfiguration@ContextConfiguration("file:src/test/java/spring-config.xml")@ActiveProfiles("dev")@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)public abstract class BaseControllerTest{protected MockMvc mvc; @Autowiredprivate WebApplicationContext context; //获取系统上下文 protected WebApplicationContext getCtx() {return this.context; } //初始化方法@Beforepublic void setup() throws SQLException {this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); } //封装返回结果protected String getMockResultStr(MockHttpServletRequestBuilder requestBuilder) {try {MvcResult mvcResult = this.mockMvc.perform(requestBuilder).andExpect(status().isOk()).andDo(MockMvcResultHandlers.print()).andReturn(); MockHttpServletResponse response = mvcResult.getResponse(); response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); return response.getContentAsString(); } catch (Exception e) {e.printStackTrace(); return null; }}}
代码说明
- @RunWith(SpringJUnit4ClassRunner.class) 注解表明使用SpringJUnit4ClassRunner来运行测试用例。
- @WebAppConfiguration 注解表明使用的ApplicationContext将是WebApplicationContext类型的;value属性指定web应用的根;同时,他必须与 @ContextConfiguration一同使用。
- @ContextConfiguration注解的作用是导入我们需要的配置文件或者类,这里指定了SpringMVC的配置文件
- @ActiveProfiles 注解是指定单元测试连接的环境。
- @TransactionConfiguration 注解是用与管理spring事务的。
- MockHttpServletRequest 类为了模拟HttpServletRequest 对象,可以通过它来设置请求头,这在需要鉴权的接口测试中十分实用。
- MockMvc 实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快,不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
MvcResult mvcResult = this.mockMvc.perform(requestBuilder).andExpect(status().isOk()).andDo(MockMvcResultHandlers.print()).andReturn();
- perform方法是执行一个RequestBuilder请求,调用Controller的业务处理逻辑。
- andExpect 方法是添加执行完成后的断言,添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确,此处是验证状态是否是200
- andDo 方法是添加一个结果处理器,比如再此处是andDo(MockMvcResultHandlers.print())输出整个响应结果信息,可以在调试的时候使用。
- andReturn:方法是执行完成后返回相应的结果。
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。
- MockHttpServletRequestBuilder.post(String urlTemplate, Object… urlVariables):同get类似,但是是post方法,通过param 方法来设置请求参数。
get请求测试
get请求的测试就是调用MockMvcRequestBuilders的get方法, 在该方法中传入接口地址。
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/v1/works/lineup/set").param("id", "123").param("first_flag", String.valueOf(true)); String result = getMockResultStr(requestBuilder);
post请求测试
post请求的测试就是调用MockMvcRequestBuilders的post方法, 在该方法中传入接口地址。
MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/v1/blockly/copy").param("id", "1211"); success(requestBuilder);
文件上传测试
【SpringMVC框架如何与Junit整合看这个就够了】文件上传的测试就是调用MockMvcRequestBuilders的multipart方法, 在该方法中传入接口地址。
File file = new File(RestArmWorksControllerTest.class.getClassLoader().getResource("20201102172053.png").toURI()); MockMultipartFile mockMultipartFile = new MockMultipartFile("file", "20201102172053.png", "", new FileInputStream(file)); MockMultipartHttpServletRequestBuilder servletRequestBuilder = MockMvcRequestBuilders.multipart("/creation/fileUpload.do").file(mockMultipartFile); String result = getMockResultStr(servletRequestBuilder);
发送一个json格式的数据到Controller层
String requestJson = JSONObject.toJSONString(folderInfo); MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post("//v1/works/save").contentType(MediaType.APPLICATION_JSON).content(requestJson);
返回结果是视图请求的单元测试
那么,问题来了,如果一个接口的返回结果是视图,那么这个接口的单元测试该如何写呢?比如下面这个接口:
@RequestMapping(value = "https://www.it610.com/edit")public String edit(ModelMap model, HttpServletRequest request, HttpServletResponse response) {Long scriptId = null; if (StringUtils.isNotBlank(request.getParameter("scriptId"))) {scriptId = Long.parseLong(request.getParameter("scriptId")); }if (scriptId != null) {MallSuperscript mallSuperscript = superScriptService.getScriptById(scriptId); model.addAttribute("superScript", mallSuperscript); }model.addAttribute("scriptTypeMap", ScriptType.toMap()); logger.info("角标编辑页面返回成功"); return "manage/superScript/edit"; }
这个接口返回的是一个视图,就是名称为edit.jsp页面。它的测试方法可以像下面这样写。
@Testpublic void testEdit() throws Exception {MvcResult mvcResult = mvc.perform(get("/manage/tab2/superScript/edit").sessionAttr("adminid", "1111").sessionAttr("platformid", 1001L).param("scriptId", "1111")).andExpect(status().isOk()).andDo(print()).andReturn(); assertEquals("manage/superScript/edit", mvcResult.getModelAndView().getViewName()); }
通过mvcResult.getModelAndView().getViewName()获取视图的名称。
直接测试一个service的方法
上面的那些测试针对的都是Controller层的接口,那么如果要测试一个service层的方法,该如何处理呢?
public class MallMailJobTest extends BaseControllerTest {private MallMailJob mallMailJob; @Override@Beforepublic void setup() throws SQLException {super.setup(); mallMailJob = getCtx().getBean(MallMailJob.class); }/*** * @throws Exception*/@Testpublic void testExecute() throws Exception {mallMailJob.execute(); }
被测试的MallMailJob类也可以通过@Autowired 注解直接注入进Spring IOC容器中。拿到被测试类的实例之后就可以直接调用被测试的方法,是不是灰常的简单呀。
总结
本文详细介绍在SpringMVC任何使用Junit框架。首先介绍了如何引入依赖,接着介绍了编写一个测试基类,并且对其中涉及的各个注解做了一个详细说明。最后就是罗列了各种测试情况。
到此这篇关于SpringMVC框架如何与Junit整合看这个就够了的文章就介绍到这了,更多相关SpringMVC整合Junit内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- android第三方框架(五)ButterKnife
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 如何寻找情感问答App的分析切入点
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus使用queryWrapper如何实现复杂查询
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 如何在Mac中的文件选择框中打开系统隐藏文件夹
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- java中如何实现重建二叉树
- Linux下面如何查看tomcat已经使用多少线程