Spring+Junit+Mock测试web项目,即Controller
准备:Maven依赖
<!-- Spring和MVC的包这里不列出来了,webmvc,aspects,orm,其他maven会自动导 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version> 4.1.3.RELEASE</version>
<scope>provided</scope>
</dependency>
1、控制器例子
package henu.controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import henu.entity.Exam; /**
* @ClassName: MockTestController <br/>
* @Describtion: Mock框架测试用例. <br/>
* @date: 2018年4月19日 下午2:02:47 <br/>
* @author Beats <br/>
* @version v1.0
*/
@Controller
public class MockTestController { @RequestMapping("/hello")
@ResponseBody
public String hello(String hello) {
return hello + " world!";
} @RequestMapping("/json")
@ResponseBody
public Exam json(String json) {
Exam e = new Exam();
e.setId(123);
e.setSubject(json);
return e;
}
}
2、测试例子
package henu.test; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; import javax.annotation.Resource; import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext; /**
* @ClassName: TestMock <br/>
* @Describtion: 使用Spring集成的Mock框架测试web应用的控制器. <br/>
* @date: 2018年4月19日 下午1:58:22 <br/>
* @author Beats <br/>
* @version v1.0
*/
//这个必须使用junit4.9以上才有
@RunWith(SpringJUnit4ClassRunner.class)
//单元测试的时候真实的开启一个web服务,测试完毕就关闭
@WebAppConfiguration
//配置事务的回滚,对数据库的增删改都会回滚,便于测试用例的循环利用
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
@Transactional
@ContextConfiguration(locations={"classpath:spring.xml","classpath:springmvc.xml"})
//@ContextConfiguration(locations="classpath:spring*.xml")
public class TestMock { /**
* web应用的上下文
*/
@Resource
private WebApplicationContext context;
/**
* Mock框架的核心类
*/
private MockMvc mockMVC; @Before
public void initMockMVC() {
this.mockMVC = MockMvcBuilders.webAppContextSetup(context).build();
} @Test
public void testStringResult() throws Exception{ String res = mockMVC.perform(get("/hello")
.param("hello", "This is my")
.contentType(MediaType.TEXT_HTML)
.accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())//期望值
.andDo(print())//打印结果
.andReturn().getResponse().getContentAsString();//结果字符串
System.err.println(res); } @Test
public void testJsonResult() throws Exception{ String res = mockMVC.perform(get("/json")
.param("json", "JAVA")
.param("hah", "hah")
//请求参数的类型
.contentType(MediaType.TEXT_HTML)
//希望服务器返回的值类型
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())//期望值
.andDo(print())//打印结果
.andReturn().getResponse().getContentAsString();//结果字符串
System.err.println(res);
} @Test
public void testModelResult() throws Exception{ String res = mockMVC.perform(get("/json")
.param("json", "JAVA")
.param("hah", "hah")
//请求参数的类型
.contentType(MediaType.TEXT_HTML)
//希望服务器返回的值类型
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())//期望值
.andDo(print())//打印结果
.andReturn().getResponse().getContentAsString();//结果字符串
System.err.println(res);
} @Test
public void testOthers() throws Exception {
byte[] bytes = new byte[] {1, 2};
mockMVC.perform(
fileUpload("/user/{id}/icon", 1L).file("icon", bytes)) //执行文件上传
.andExpect(model().attribute("icon", bytes)) //验证属性相等性
.andExpect(view().name("success")); //验证视图 // mockMvc.perform(post("/user").param("name", "zhang")) //执行传递参数的POST请求(也可以post("/user?name=zhang"))
// .andExpect(handler().handlerType(UserController.class)) //验证执行的控制器类型
// .andExpect(handler().methodName("create")) //验证执行的控制器方法名
// .andExpect(model().hasNoErrors()) //验证页面没有错误
// .andExpect(flash().attributeExists("success")) //验证存在flash属性
// .andExpect(view().name("redirect:/user")); //验证视图
}
}
函数解释:
/**
* perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;
* get:声明发送一个get请求的方法。MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根据uri模板和uri变量值得到一个GET请求方式的。另外提供了其他的请求的方法,如:post、put、delete等。
* param:添加request的参数,如上面发送请求的时候带上了了pcode = root的参数。假如使用需要发送json数据格式的时将不能使用这种方式
* andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确(对返回的数据进行的判断);
* andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台(对返回的数据进行的判断);
* andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理(对返回的数据进行的判断)
*/
注意上面contentType需要设置成MediaType.APPLICATION_JSON,即声明是发送“application/json”格式的数据。使用content方法,将转换的json数据放到request的body中。
没有Mock框架怎么样?
在spring开发中,可以使用Spring自带的MockMvc这个类进行Mock测试。
所谓的Mock测试,这里我举一个通俗易懂的例子,像servlet API中的HttpServletRequest对象是Tomcat容器生成的。我们无法手动的new出来,于是就有了所谓的Mock测试
运行配置
用到的注解:
- RunWith(SpringJUnit4ClassRunner.class): 表示使用Spring Test组件进行单元测试;
- WebAppConfiguration: 使用这个Annotate会在跑单元测试的时候真实的启动一个web服务,然后开始调用Controller的Rest API,待单元测试跑完之后再将web服务停掉;
- ContextConfiguration: 指定Bean的配置文件信息,可以有多种方式,这个例子使用的是文件路径形式,如果有多个配置文件,可以将括号中的信息配置为一个字符串数组来表示;controller,component等都是使用注解,需要注解指定spring的配置文件,扫描相应的配置,将类初始化等。
- TransactionConfiguration(transactionManager="transactionManager",defaultRollback=true)配置事务的回滚,对数据库的增删改都会回滚,便于测试用例的循环利用
为什么要进行事务回滚:
- 测试过程对数据库的操作,会产生脏数据,影响我们数据的正确性
- 不方便循环测试,即假如这次我们将一个记录删除了,下次就无法再进行这个Junit测试了,因为该记录已经删除,将会报错。
- 如果不使用事务回滚,我们需要在代码中显式的对我们的增删改数据库操作进行恢复,将多很多和测试无关的代码
Mock全局配置
mockMvc = webAppContextSetup(wac)
.defaultRequest(get("/user/1").requestAttr("default", true)) //默认请求 如果其是Mergeable类型的,会自动合并的哦mockMvc.perform中的RequestBuilder
.alwaysDo(print()) //默认每次执行请求后都做的动作
.alwaysExpect(request().attribute("default", true)) //默认每次执行后进行验证的断言
.build(); mockMvc.perform(get("/user/1"))
.andExpect(model().attributeExists("user"));
Spring+Junit+Mock测试web项目,即Controller的更多相关文章
- Spring Boot构建的Web项目如何在服务端校验表单输入
本文首发于个人网站:Spring Boot构建的Web项目如何在服务端校验表单输入 这个例子用于演示在Spring Boot应用中如何验证Web 应用的输入,我们将会建立一个简单的Spring MVC ...
- Spring mvc创建的web项目,如何获知其web的项目名称,访问具体的链接地址?
Spring mvc创建的web项目,如何获知其web的项目名称,访问具体的链接地址? 访问URL: http://localhost:8090/firstapp/login 在eclipse集成的 ...
- 使用IDEA搭建一个 Spring + Spring MVC + Mybatis 的Web项目 ( 零配置文件 )
前言: 除了mybatis 不是零配置,有些还是有xml的配置文件在里面的. 注解是Spring的一个构建的一个重要手段,减少写配置文件,下面解释一下一些要用到的注解: @Configuration ...
- spring boot + Thymeleaf开发web项目
"Spring boot非常适合Web应用程序开发.您可以轻松创建自包含的HTTP应用.web服务器采用嵌入式Tomcat,或者Jetty等.大多数情况下Web应用程序将使用 spring- ...
- spring学习(四) ———— 整合web项目(SSH)
清楚了spring的IOC 和 AOP,最后一篇就来整合SSH框架把,记录下来,以后应该会用的到. --WH 一.web项目中如何使用spring? 当tomcat启动时,就应该加载spring的配置 ...
- spring(四) 手动整合web项目(SSH)
清楚了spring的IOC 和 AOP,最后一篇就来整合SSH框架把,记录下来,以后应该会用的到. --WH 一.web项目中如何使用spring? 当tomcat启动时,就应该加载spring的配置 ...
- spring boot之创建web项目并访问jsp页面
1,创建spring boot的web项目 刚创建好的项目路径如下: 2,pom中要有下面的依赖 <dependency> <groupId>org.springframewo ...
- Spring Boot快速开发Web项目
我们以前使用Spring框架的时候,需要首先在pom文件中增加对相关的的依赖,然后新建Spring相关的xml文件,而且往往那些xml文件还不会少.然后继续使用tomcat或者jetty作为容器来运行 ...
- IDEA创建一个Spring MVC 框架Java Web项目,Gradle构建
注:此篇有些细节没写出,此文主要写重要的环节和需要注意的地方,轻喷 新建项目 选择Gradle , 勾选java 和 web.之后就是设定项目路径和名称,这里就不啰嗦了. build.gradle文件 ...
随机推荐
- Python,PyCharm2017安装教程,包含注册码[转载]
一,安装PyCharm 1.下载PyCharm 进入https://www.jetbrains.com/pycharm/download/#section=windows官网下载页面,可以到到PyCh ...
- numpy.zeros(shape, dtype=float, order='C')
numpy.zeros Return a new array of given shape and type, filled with zeros. Parameters: shape : int o ...
- 奇异值分解(SVD)实例,将不重要的特征值改为0,原X基本保持不变
>> s = rand(5,7) s = 0.4186 0.8381 0.5028 0.1934 0.6979 0.4966 0.6602 0.8462 0.0196 0.7095 ...
- eclipse个人觉得有用的快捷键
CTRL+SHIFT+F 自动整理代码格式 CTRL+M 最大/还原当前编辑窗口 CTRL+/ 注释当前行 CTRL+1 快速修复 CTRL+D 删除当前行 SHIFT+ENTER 在当前行前面插入空 ...
- macOS 安装 Docker
系统要求 Docker for Mac 要求系统最低为 macOS 10.10.3 Yosemite,或者 2010 年以后的 Mac 机型,准确说是带 Intel MMU 虚拟化的,最低 4GB 内 ...
- assert.fail()
assert.fail(message) assert.fail(actual, expected[, message[, operator[, stackStartFunction]]]) oper ...
- 基本算法思想之递推算法思想(C++语言描述)
递推算法是非常常用的算法思想,在数学计算等场合有着广泛的应用.递推算法适合有明显公式规律的场合. 递推算法基本思想 递推算法是一种理性思维莫斯的代表,根据已有的数据和关系,逐步推到而得到结果.递推算法 ...
- swiper实现左右滑动图片
ref:http://www.swiper.com.cn/usage/index.html help:https://segmentfault.com/a/1190000002962202 src: ...
- vivado中如何调用chipscope或者impact
vivado中并没有集成chipscope和impact,所以需要安装ISE,安装完ISE后进行以下操作: 1) 选择环境变量中的系统变量,新建以下变量 XILINX ...
- java线程基础知识----java线程模型
转载自http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html 1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标 ...