springboot2.0入门(四)----mock模拟测试+单元测试
一、本节主要记录模拟测试、单元测试:
二、mock 测试
1.1什么是Mock?
在面向对象程序设计中,模拟对象(英语:mock object,也译作模仿对象)是以可控的方式模拟真实对象行为的假的对象。比如:对象B依赖于对象A,但是A代码还没写是一个空类空方法不能用,我们来mock一个假的A来完成测试。
/**
* @author Levi
* @date 2019/10/4 21:09
*/
//@Transactional
@Slf4j
@SpringBootTest
public class MockTest {
private MockMvc mockMvc;
//它是不在spring容器中的,需要手动引入
@Before
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(new AnimalController()).build();
}
@Test
public void saveArticle() throws Exception {
//直接将前面请求的例子粘贴过来会自动分行
String article = "{\n" +
" \"id\": 1,\n" +
" \"name\": \"pig\",\n" +
" \"type1\": \"\",\n" +
" \"birthDate\":\"2019-10-04T05:10:10\",\n" +
" \"animalList\":[{\"name\":\"dog\",\"type\":5},{\"name\":\"dog\",\"type\":10}]\n" +
"}";
MvcResult result = mockMvc.perform(
MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/animals")
.contentType("application/json").content(article))
.andExpect(MockMvcResultMatchers.status().isOk())//返回状态200为成功
.andExpect(MockMvcResultMatchers.jsonPath("$.data.name").value("pig"))//返回属性name为pig
.andExpect(MockMvcResultMatchers.jsonPath("$.data.animalList[0].type").value(5))//返回属性type需要为5
.andDo(print())
.andReturn();
log.info(result.getResponse().getContentAsString());
}
}
测试代码;

返回结果;
2.1 @SpringBootTest 注解说明:
是用来创建Spring的上下文ApplicationContext,保证测试在上下文环境里运行。单独使用@SpringBootTest不会启动servlet容器。所以只是用SpringBootTest 注解,不可以使用@Resource和@Autowired等进行依赖注入(准确的说是可以使用,但被注解的bean为null)。
2.2 @Transactional
可以使单元测试进行事务回滚,以保证数据库表中没有因测试造成的垃圾数据,再就是保证单元测试可以反复执行;
不要在 Spring Boot 集成测试中使用 @Transactional
不推荐使用,他会删表,不会删除数据,他的事务是在内存中进行的,模拟的结果是不正确的,和真实环境有差距的;
2.3 MockMvc有以下几个基本的方法:
- perform : 执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理。
- contentType:发送请求内容的序列化的格式,"application/json"表示JSON数据格式
- andExpect: 添加RequsetMatcher验证规则,验证控制器执行完成后结果是否正确,或者说是结果是否与我们期望(Expect)的一致。
- andDo: 添加ResultHandler结果处理器,比如调试时打印结果到控制台
- andReturn: 最后返回相应的MvcResult,然后进行自定义验证/进行下一步的异步处理
3.1怎样在真实的servlet容器中运行
在测试类上面额外加上这样两个注解,mockMvc使用@Resource自动注入,删掉Before注解及setUp函数

添加
@RunWith(SpringRunner.class) @AutoConfigureMockMvc 注解后,即在spring中运行;
3.1 @RunWith注解
RunWith方法为我们构造了一个的Servlet容器运行运行环境,并在此环境下测试。然而为什么要构建servlet容器?因为使用了依赖注入,注入了MockMvc,在上个例子里面是我们自己构建的。而@AutoConfigureMockMvc注解,该注解表示 MockMvc由我来构建,你只负责用就可以了。这种写法是为了让测试在Spring容器环境下执行。Spring的容器环境是啥呢?比如常见的 Service Dao 都是Spring容器里的bean,装载到容器里面,都可以使用@Resource和@Autowired来引用。

注入并使用了@Runwith,少了这个注解,service注入不进去,会报空指针
4、轻量级测试(注入指定的Controller和service进行测试)
1、在RunWith的AutoConfigureMockMvc注解的共同作用下,启动了SpringMVC的运行容器。并且把项目中所有的@Bean全部都注入进来。把所有的bean都注入进来是不是略显臃肿,真实的单元测试有可能上千个,这样会拖慢单元测试的效率。如果我只是想测试一下web层,或者说的控制层Controller,怎么办?或者说我只想测试一下ArticleRestController,你不要把应用中所有的bean都注入。
/**
* 在轻量级容器中的测试
* @author Levi
* @date 2019/10/4 21:09
*/
//@Transactional
@Slf4j
//@SpringBootTest
@WebMvcTest //注入所有controller 甚至可以注入指定controller @WebMvcTest(AnimalController.class)
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
public class MockTestSimple {
@Resource
private MockMvc mockMvc;
@MockBean
private AnimalService animalService;
@Test
public void saveArticle() throws Exception {
String animal = "{\n" +
" \"id\": 1,\n" +
" \"name\": \"pig\",\n" +
" \"type\": \"\",\n" +
" \"birthDate\":\"2019-10-04T05:10:10\",\n" +
" \"animalList\":[{\"name\":\"dog\",\"type\":5},{\"name\":\"dog\",\"type\":10}]\n" +
"}";
log.error("animal"+animalService.saveAnimal(null));
ObjectMapper objectMapper = new ObjectMapper();
Animal animalObj = objectMapper.readValue(animal,Animal.class);
//打桩--当controller调用改service时,模拟返回一个ok
when(animalService.saveAnimal(animalObj)).thenReturn("ok");
MvcResult result = mockMvc.perform(
MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/animals")
.contentType("application/json").content(animal))
.andExpect(MockMvcResultMatchers.status().isOk())//返回状态200为成功
.andExpect(MockMvcResultMatchers.jsonPath("$.data.name").value("pig"))//返回属性name为pig
.andExpect(MockMvcResultMatchers.jsonPath("$.data.animalList[0].type").value(5))//返回属性type需要为5
.andDo(print())
.andReturn();
log.info(result.getResponse().getContentAsString());
}
}

可以查看到电泳到的sevice 不是“animal测试”,而是“ok”
springboot2.0入门(四)----mock模拟测试+单元测试的更多相关文章
- Mock 模拟测试简介及 Mockito 使用入门
Mock 是什么mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法.这个虚拟的对象就是mock对象.mock对象就是真实对象在调试期间的代 ...
- Python 的mock模拟测试介绍
如何不靠耐心测试 可能我们正在写一个社交软件并且想测试一下"发布到Facebook的功能",但是我们不希望每次运行测试集的时候都发布到Facebook上. Python的unitt ...
- Springboot2.0入门介绍
Springboot目前已经得到了很广泛的应用,why这么牛逼? Springboot让你更容易上手,简单快捷的构建Spring的应用 Spring Boot让我们的Spring应用变的更轻量化.比如 ...
- springboot2.0入门(三)----定义编程风格+jackjson使用+postMan测试
一.RESTFul风格API 1.优点: )看Url就知道要什么资源 )看http method就知道针对资源干什么 )看http status code就知道结果如何 HTTP方法体现对资源的操作: ...
- springboot2.0入门(八)-- profile启动文件配置
一.不同环境使用不同配置文件 将application.yml文件拷贝三份,在文件末尾分别对应开发/生产/测试,dev/prod/test/文件夹,其中application.yml 中默认激活开发环 ...
- springboot2.0入门(七)-- 自定义配置文件+xml配置文件引入
一.加载自定义配置文件: 1.新建一个family.yam文件,将上application.yml对象复制进入family family: family-name: dad: name: levi a ...
- springboot2.0入门(九)-- springboot使用mybatis-generator自动代码生成
一.配置文件引入 插件引入,引入 <plugin> <groupId>org.mybatis.generator</groupId> <artifactId& ...
- springboot2.0入门(六)-- ymal语法、数据校验
一.基本使用 1.ymal语法是一种更符合人类命名习惯的语法: # 1. 一个家庭有爸爸.妈妈.孩子. # 2. 这个家庭有一个名字(family-name)叫做“happy family” # 3. ...
- springboot2.0入门(五)--swagger2接口API构建
一.特点 代码变,文档变.只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性. 跨语言性,支持 40 多种语言. Swagger UI 呈现出来的是一份可 ...
随机推荐
- 基本mysql语句
一 select语句 基本语法 select 列名1,列名2 //可以使用完全限定的列名 tables.列名 form tables 过滤(where ) 分组(group ...
- 网站页面顶部出现空白行字符的原因以及完美解决办法
转自个人博客:https://www.hurbai.com 有时候网页头部会出现一个空白行,查看源码发现body开头初有一个非法字符 // 如果是Windows系统,修改为:$WIN = 1; $W ...
- User space(用户空间) 与 Kernel space(内核空间)
出处: User space 与 Kernel space (整理)用户空间_内核空间以及内存映射 学习 Linux 时,经常可以看到两个词:User space(用户空间)和 Kernel spac ...
- 牛客 216D 消消乐 (二分图最小点覆盖)
大意: 给定棋盘, 每次消除一行或一列, 求最小次数使得消除完所有'*'. 裸的二分图最小点覆盖. 二分图的最小点覆盖等于最大匹配, 输出方案时从所有左部未盖点开始标记交替路上的点, 最后左部所有未标 ...
- Spring、SpringMVC版本及配置
一.Spring版本 Spring的最新版本是Spring 5.x,Spring 4.x的最后版本是Spring 4.3.x,会维护到2020年(Spring的GitHub主页对此有说明). 二.Sp ...
- IntelliJ IDEA 搭建 Go 开发环境
本文介绍 Windows7 x64 基于 IntelliJ IDEA 搭建 Go 语言开发环境.主要是一些操作过程截图以及简单文字描述,如有不清楚的地方,欢迎指正.所有软件使用当前(2016.12. ...
- Python字符串常用的方法——真心觉得比java,c好用
# Strings have many methods wo can use rand_string=" life is a beautiful struggle " print( ...
- 给postmessage加上callback方法
postmessage双向通信中,是不能使用回调函数的. window.postmessage({msg:'hello',callback:function(e){ do something with ...
- winfrom_权限设置_TreeView的相关问题
1.获取TreeView的值: 循环TreeView,获取checked每个节点的Text,串起来用逗号“,”隔开,保存到数据库. List<string> list = new List ...
- 设计模式风格<二>;消息总线
以前开发的动车模拟驾驶系统,有好几个软件(不在一台机器上),他们互相之间通信,因此每个软件要配置每个模块的IP和端口,就是每个模块都要知道别的模块的端口和IP. 这样有个重复的地方,B模块和C模块都要 ...