Spring Boot中采用Mockito来mock所测试的类的依赖(避免加载spring bean,避免启动服务器)
最近试用了一下Mockito,感觉真的挺方便的。举几个应用实例:
1,需要测试的service中注入的有一个dao,而我并不需要去测试这个dao的逻辑,只需要对service进行测试。这个时候怎么办呢,mockito就可以做到把这个dao给mock了,调用这个dao的方法会直接返回预设的值,不会去真正的执行dao里的逻辑,省时省力,专注于眼前。
2,不想在单测时启动容器,加载一堆没有用的东西。这个时候你就可以把你的单元测试写成一个纯junit的test类,可以飞快的跑完测试逻辑,不用等待server加载,spring加载等乱七八糟的过程。当然这个只是一个附带的好处,主要还是1。
下面写来一段简单的代码,稍作讲解(项目基于spring boot,其实无所谓,只要有junit,mockito,spring依赖即可,数据库配置什么的也需要自己已经配好了,这里不做说明)。
先来实体类:
/**
* Created by zp on 2017/11/20.
*/
@Data
@Builder
@Entity
@Table
public class Model {
private Long id;
private String name;
}
Lombok注解就不多解释了。标准Bean
DAO:
/**
* Created by zp on 2017/11/20.
*/
@Repository
public class ModelDao {
public Model getModel(Long id){
return Model.builder().id(id).name("model from dao ").build();
}
}
最简单的dao,实际上应该是访问数据库,为了方便,这里构建一个对象返回出去。注意name是model from dao,由这个dao得出的对象name都会是这个,mock出来的会是另一个。
Service:
/**
* Created by zp on 2017/11/20.
*/
@Service
public class ModelServiceImpl implements ModelService {
@Autowired
ModelDao modelDao;
@Override
public Model getModel(Long id) {
return modelDao.getModel(id);
}
}
接口的实现类,ModelService就一个方法,这里不写了。
好了,基础的service和dao,bean都有了。现在我们要对ModelService做测试,按照传统的方式,Tests代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests { @Autowired
ModelService modelService; @Test
public void contextLoads() {
Model model = modelService.getModel(3L);
System.out.println(model);
Assert.assertEquals(3l,model.getId().longValue());
} }
这个会加载spring的一堆依赖,然后按照spring的注入规则,把ModelService注入进来,同时也会把ModelDao注入到ModelService中,运行一下,熟悉的画面:
单测会顺利通过:
控制台也会打印如下输出:
可见这个是真的走的dao的代码逻辑,如果是真实业务代码,那这就去读数据库了。
这个流程虽然也能跑,但是牵扯的东西太多,还要保证ModelDao能正确注入,运行;还要加载一堆spring/server的东西,耗时耗力。
下面就用mockito来改写一下Tests代码,结果如下:
public class DemoApplicationTests { @InjectMocks
private ModelService modelService= new ModelServiceImpl(); @Mock
private ModelDao modelDao; @Before
public void setUp() {
MockitoAnnotations.initMocks(this); when(modelDao.getModel(any(Long.class)))
.thenReturn(Model.builder().id(1L).name("model from mock").build());
} @Test
public void contextLoads() {
Model model = modelService.getModel(3L);
System.out.println(model);
Assert.assertEquals(3l,model.getId().longValue());
} }
主要有以下几点变化:
1,@RunWith(SpringRunner.class),@SpringBootTest这两个注解去掉,整个Test清除了Spring Test依赖,可以避免加载额外的东西;
2,Autowire 改成如下:
@InjectMocks
private ModelService modelService= new ModelServiceImpl();
不再Autowire,而是InjetMocks,并且要自己new出Service对象;
3,添加Mock Dao的代码
@Mock
private ModelDao modelDao;
表示这个对象是需要Mock的
4,初始化Mockito,编写Mock逻辑
@Before
public void setUp() {
MockitoAnnotations.initMocks(this); when(modelDao.getModel(any(Long.class)))
.thenReturn(Model.builder().id(1L).name("model from mock").build());
}
重点在when()这个方法里,when函数以需要mock的方法作为参数,any表示任何输入,thenReturn设置返回的值。
这句when的意思就是当碰到modelDao的getModel函数,传入参数为任何一个Long,则直接返回一个新的,自己构建的Model对象,避免执行ModelDao的真实代码。
先看一下代码,mock后ModelDao无论输入任何参数,都会返回一个id为1,name为model from mock的Model对象,这个单测肯定是跑不过的。让我们来验证一下:
果然跟我们预期的一样,并且完全没有加载spring,直接一下就跑完了测试。
Spring Boot中采用Mockito来mock所测试的类的依赖(避免加载spring bean,避免启动服务器)的更多相关文章
- Druid Spring Boot Starter 从配置到简单运行 -解决zone不匹配 -解决dataSource加载失败
Druid Spring Boot Starter 中文 | English Druid Spring Boot Starter 用于帮助你在Spring Boot项目中轻松集成Druid数据库连接池 ...
- 在Spring Boot中配置web app
文章目录 添加依赖 配置端口 配置Context Path 配置错误页面 在程序中停止Spring Boot 配置日志级别 注册Servlet 切换嵌套服务器 在Spring Boot中配置web a ...
- 在Spring Boot中使用数据缓存
春节就要到了,在回家之前要赶快把今年欠下的技术债还清.so,今天继续.Spring Boot前面已经预热了n篇博客了,今天我们来继续看如何在Spring Boot中解决数据缓存问题.本篇博客是以初识在 ...
- spring boot中的约定优于配置
Spring Boot并不是一个全新的框架,而是将已有的Spring组件整合起来. Spring Boot可以说是遵循约定优于配置这个理念产生的.它的特点是简单.快速和便捷. 既然遵循约定优于配置,则 ...
- 再谈Spring Boot中的乱码和编码问题
编码算不上一个大问题,即使你什么都不管,也有很大的可能你不会遇到任何问题,因为大部分框架都有默认的编码配置,有很多是UTF-8,那么遇到中文乱码的机会很低,所以很多人也忽视了. Spring系列产品大 ...
- spring boot 中文文档地址
spring boot 中文文档地址 http://oopsguy.com/documents/springboot-docs/1.5.4/index.html Spring Boot 参考指 ...
- Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置
用过 Spring Boot 的小伙伴都知道,我们只需要在项目中引入 spring-boot-starter-web 依赖,SpringMVC 的一整套东西就会自动给我们配置好,但是,真实的项目环境比 ...
- spring mvc 和spring boot 中注解的使用
1 spring mvc和spring boot之间的关系 spring boot包含spring mvc.所以,spring mvc的注解在spring boot总都是可以用的吗? spring b ...
- spring boot中的底层配置文件application.yam(application.property)的装配原理初探
*在spring boot中有一个基础的配置文件application.yam(application.property)用于对spring boot的默认设置做一些改动. *在spring boot ...
随机推荐
- SQL SERVER 根据地图经纬度计算距离函数
前些天客户提出一个这样的要求:一个手机订餐网,查询当前所在位置的5公里范围的酒店,然后客户好去吃饭. 拿到这个请求后,不知道如何下手,静静地想了一下,在酒店的表中增加两个字段,用来存储酒店所在的经度和 ...
- 一款低延迟的分布式数据库同步系统--databus
每次看到马路对面摩托罗拉的大牌子,都想起谷歌125亿美元收购摩托罗拉移动,后来又以29亿美元卖给联想的事情.谷歌所做的决策都比较考虑长远利益,在这串交易中,谷歌获得了摩托罗拉最有价值的几千项专利,稳健 ...
- Arrays.asList () 不可添加或删除元素的原因
Java中奖数组转换为List<T>容器有一个很方便的方法 Arrays.asList(T ... a),我通过此方法给容器进行了赋值操作,接着对其进行 添加元素,却发现会抛出一个(jav ...
- 详解变量声明加 var 和不加 var 的区别
在全局作用域中声明变量加 var 关键字和不加 var ,js 引擎都会将这个变量声明为全局变量,在实际运行时,两种声明方式的变量的行为也是几乎一致的.但是在全局作用域下是否声明一个变量的 时候加va ...
- Java IO(Properties/对象序列化/打印流/commons-io)
Java IO(Properties/对象序列化/打印流/commons-io) Properties Properties 类表示了一个持久的属性集.Properties 可保存在流中或从流中加载. ...
- Java实用知识记录 —— 截止到Java8
记录Java实用知识点,截止(包括)到Java8,只作概要的描述,不涉及到具体细节.变量:int.long的包装类支持无符号位操作,即其在内存中的位可以用来全部表示正数."_"可以 ...
- HTML5-前端开发很火且工资很高?
前言 晚上逛论坛看到一篇对从事HTML5前端开发的文章写的非常不错,和目前的市场形势差不多,然后我在其基础上给大家进行加工总结一下分享给大家.今天我们谈论的话题是<<为什么从事HTML5前 ...
- SPARK 创建新任务
1.应用程序创建 SparkContext 的实例 sc 2.利用 SparkContext 的实例来创建生成 RDD 3.经过一连串的 transformation 操作,原始的 RDD 转换成为其 ...
- 微软Tech Summit 2017,等你来打Call
2017年10月31至11月3日,由微软举办的Tech Summit 2017技术暨生态大会将在北京盛大举办,要在北京连开四天.今年的技术大会看头十足,不仅有大咖级人物带来十二大主题课程,更有三天四场 ...
- ASP.NET没有魔法——Identity与Owin
上篇文章介绍了如何在ASP.NET MVC项目中引入Identity组件来实现用户注册.登录及身份验证功能,并且也提到了Identity是集成到Owin中的,本章就来介绍一下什么是Owin以及如何使用 ...