spring /spring boot中mock
1 Mockito简介
1.1 Mockito是什么
Mockito是一个简单的流行的Mock框架。它允许你创建和配置mock对象。使用Mockito可以明显的简化对外部依赖的测试类的开发。一般使用 Mockito 需要执行下面三步:
模拟并替换测试代码中外部依赖;
执行测试代码;
验证测试代码是否被正确的执行。
1.2 Mock是什么
Mock测试就是在测试过程中,对某些不容易构造或者不容易获取的对象,用一个虚拟的Mock对象来创建以便测试的测试方法。
Mock最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。
2 Mockito在Spring框架中的使用
2.1 依赖包
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>2.21.0</version> <scope>test</scope></dependency> |
Mockito在Spring可以通过配置文件和注解的方式使用
2.2 通过xml配置文件使用Mockito
Mockito创建方式有两种:mock,spy。mock为一个interface提供一个虚拟的实现,spy为object加一个动态代理,实现部分方法的虚拟化,但是需要赋予一个instance。
Mockito提供了factory的方法用来创建mock和spy。
假设构造系统中有serviceA,serviceB,serviceC,其中serviceA依赖serviceB依赖serviceC。serviceC是最基本的。现在需要对其中serviceA进行测试,但其serviceC需要依赖于外部环境,而这个环境需要复杂而且不稳定的数据库。这时需要mock或spy掉serviceC。
注:无论是spring框架还是spring boot框架,如果集成了MyBatis,因Mybatis中Mapper基于动态代理实现,则其对应的mapper接口只能基于xml文件配置方式注入mock或spy。
具体解释参考:https://sq.163yun.com/blog/article/169561874192850944
第一步:在配置文件中注入mock:
<bean id="serviceC" class="org.mockito.Mockito"factory-method="mock"> <constructor-arg value="com.x.y.x.ServiceC"></constructor-arg></bean> |
或注入spy
<bean id="serviceCInst" class="serviceCInstance"></bean><bean id="serviceC" class="org.mockito.Mockito" factory-method="spy"> <constructor-arg ref="serviceCInst"></constructor-arg></bean> |
spy需要获得一个实例。
第二步:
在测试用例中@Resource或@Autowired引入serviceC。
2.3 通过注解使用Mockito
以代码举例
@Componentpublic class OrderCreate { @Resource private OrderHelper orderHelper; public void create() { System.out.println(getAmt()); System.out.println(orderHelper.resolve()); } public int getAmt() { return 10; }} |
@Componentpublic class OrderHelper { public String resolve() { return "resolve order"; }} |
测试类:
public class MockSpringTest { @InjectMocks private OrderCreate orderCreate; @Mock private OrderHelper orderHelper; // 此mock将被注入到orderCreate @Before public void initMocks() throws Exception { MockitoAnnotations.initMocks(this); } @Test public void create() { System.out.println("start mock..."); when(orderHelper.resolve()).thenReturn("null"); orderCreate.create(); }} |
运行结果:
start mock...10null |
mock() / @Mock:创建一个mock;
spy() / @Spy:创建一个spy,提供了一种对真实对象操作的方法;
@InjectMocks:创建一个实例。被@Mock(或@Spy)注解创建的mock将被注入到用该实例中。注意: @InjectMocks标注的属性不能使用接口。
3 Mockito在Spring boot 框架中的使用
3.1 Spring Boot自带测试模块
Spring boot自身提供很多有用的工具类和注解用于测试应用,主要分两个模块:spring-boot-test包含核心组件,spring-boot-test-autoconfigure为测试提供自动配置。开发者只需要引用spring-boot-starter-test即可。它提供的测试模块中包含了Mockito。
Spring boot使用@MockBean和@SpyBean来定义Mockito的mock和spy。SpringBoot提供的@MockBean注解,用于为Applicatio nContext中的bean定义一个mock,你可以使用该注解添加新beans,或替换已存在的bean定义。该注解可直接用于测试类,也可用于测试类的字段,或用于@Configuration注解的类和字段。当用于字段时,创建mock的实例也会被注入。Mock beans每次调用完测试方法后会自动重置。
以代码举例:
@Componentpublic class MethodTest { public String One(boolean flag){ System.err.println("coming........."); String d = Two(flag); Three(); System.err.println("result data is "+d); return d; } public String Two(boolean flag){ System.err.println("coming.........two"); if(flag){ throw new IllegalAccessError(); } return "two"; } public void Three(){ System.err.println("coming.........three"); }} |
测试类 @SpyBean
@RunWith(SpringRunner.class)@SpringBootTest(classes = DemoApplication.class)public class SpyTest{ @SpyBean private MethodTest spyTest; @Test public void test3(){ when(spyTest.Two(false)).thenReturn("test"); System.err.println(spyTest.One(false)); }} |
运行结果:
coming.........twocoming.........coming.........threeresult data is testtest |
测试类 @MockBean
@RunWith(SpringRunner.class)@SpringBootTest(classes = DemoApplication.class)public class MockTest{ @MockBean private MethodTest mockTest; @Test public void test3(){ when(mockTest.One(false)).thenReturn("test"); System.err.println(mockTest.One(false)); }} |
运行结果:
test |
3.2 Spring Boot使用原生Mockito
使用方式见第2部分。
4 总结
为了统一springBoot和spring项目对Mockito的配置方式,同时解决框架中Mybaties之Mapper动态代理的mock场景,建议统一使用xml文件配置的方式。
spring /spring boot中mock的更多相关文章
- 和spring cloud/boot 学习如何管理自己的组件
案例, 功能: 需要写一个往kafka上报数据的组建. 当组建启动时,需要建立如下资源: 1, 和kafka建立若干条连接 2, 启动一个线程池 3, 启动上报一个缓冲区 问题如下: 1, 如何在sp ...
- Spring Boot中的测试
文章目录 简介 添加maven依赖 Repository测试 Service测试 测试Controller @SpringBootTest的集成测试 Spring Boot中的测试 简介 本篇文章我们 ...
- spring boot(三):Spring Boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- Spring Boot中的事务管理
原文 http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...
- Spring Boot中的注解
文章来源:http://www.tuicool.com/articles/bQnMra 在Spring Boot中几乎可以完全弃用xml配置文件,本文的主题是分析常用的注解. Spring最开始是为了 ...
- 在Spring Boot中使用Https
本文介绍如何在Spring Boot中,使用Https提供服务,并将Http请求自动重定向到Https. Https证书 巧妇难为无米之炊,开始的开始,要先取得Https证书.你可以向证书机构申请证书 ...
- Spring Boot中使用Swagger2构建强大的RESTful API文档
由于Spring Boot能够快速开发.便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API.而我们构建RESTful API的目的通常都是由于多终端的原因,这 ...
- Dubbo在Spring和Spring Boot中的使用
一.在Spring中使用Dubbo 1.Maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifa ...
- springboot(十一):Spring boot中mongodb的使用
mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...
随机推荐
- PHP 如何创建守护(daemon)进程
先讲几个概念 守护进程: Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装入时启动,在系统关闭时终止. ...
- 浅谈BFC和IFC
先说说FC,FC的含义就是Fomatting Context.它是CSS2.1规范中的一个概念. 它是页面中的一块渲染区域.而且有一套渲染规则,它决定了其子元素将怎样定位.以及和其它元素的关系和相互作 ...
- FFMPEG采集摄像头数据并切片为iPhone的HTTP Stream流
一.Windows下面编译ffmpeg 首先需要解决的问题是:在windows下面编译 ffmpeg, 并让其支持dshow, 本人把ffmpeg编译成功了, 但是编译出来的ffmpeg不支持dsho ...
- 在单链表的第i个位置后插入一个节点(阿里+腾讯等面试题总结)
时间:2014.04.26 地点:基地 ------------------------- 一.题目 题目是非常easy和基础,就是在单链表的第i个位置后插入一个节点.要求写代码,5分钟之内完毕.面腾 ...
- WCF技术我们应该如何以正确的方式去学习掌握
一.WCF技术我该如何学习? 阿笨的回答是:作为初学者的我们,那么请跟着阿笨一起玩WCF吧,阿笨将带领大家如何以正确的姿势去掌握WCF技术.由于WCF技术知识点太多了,就纯基础概念性知识都可以单独出一 ...
- [Winform]Media Player com组件应用中遇到的问题
摘要 最近一个项目中,需要用到在客户端全屏循环播放视频,当时考虑使用开源的播放器,但控制起来不方便,然后考虑既然都是windows系统,那么可以考虑使用微软自带的Media Player播放器.所以在 ...
- 在vs2012下编译出现Msvcp120d.dll 丢失的问题
之前在vs2012下编译一个opencv程序时,一直出现msvcp120d.dll文件丢失的提示信息,最初会在网上找dll下载,将其拖入系统文件夹再进行regsvr32命令操作,结果都没有解决错误,甚 ...
- 怎样用javascript获取UUID
因为javascript是单线程的东西,所以我们放一个累加变量作为id也不会反复. 但事实上javascript本身提供了能够获得唯一id的东东.还记得setTimeout()方法会返回一个唯一id用 ...
- javascript:base.superclass.constructor.call(this,config)
javascript中类的继承机制如下,有一个baseClass的类,然后为其定义两个方法,someMethod()和overwriteMethod() 1 var BaseClass = funct ...
- CATransition 实践
时间差不够,导致闪屏 CATransition *animation = [CATransition animation]; animation.delegate = self; animation. ...