mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mock对象来模拟对象的行为。
比如说你需要调用B服务,可是B服务还没有开发完成,那么你就可以将调用B服务的那部分给Mock掉,并编写你想要的返回结果。
Mock简单来理解,就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试。而这个虚拟的对象就是mock对象。
mock对象就是真实对象在调试期间的代替品。
就Mock功能而言,本身适用场景较多,但在实际项目中,引入Mock常用来解决的几类,概括起来,主要有:
- 接口间的相互依赖
- 单元测试
- 第三方接口调用
作用
1.前后端联调
比如你是一个前端页面开发,现在需要开发一个功能:
下一个订单,支付页面的接口,根据支付结果,支付成功,展示支付成功页,支付失败,展示支付失败页。要完成此功能,你需要调用后端的接口,根据返回给你的结果,来展示不同的页面。此时后端接口还没开发好,作为一个前端开发总不能等别人开发好了,你再开发,那你只有加班的命了。为了同步开发完成任务,此时,你可以根据接口文档的规定,把接口的地址和入参传过去,然后自己mock接口的不同返回界面,来完成前端的开发任务。
2.单元测试
由于单元测试仅针对当前单元进行测试,这就要求所有的内部或者外部依赖都应该是稳定的,采用mock的方法模拟跟本单元依赖的其他单元,可以将测试重点放在当前单元功能,排除外界因素干扰,提升测试精准度。
3.第三方接口依赖
在做接口自动化的时候,有时候需要调用第三方的接口,但是别人公司的接口服务不受你的控制,有可能别人提供的测试环境今天服务给你开着,别人就关掉了,给自动化接口测试带来很多的麻烦,此时就可以通过mock来模拟接口的返回数据,比如模拟各种第三方异常时的返回。
那么如何使用呢?
Mock有很多的实现框架,例如Mockito、EasyMock、Jmockit、PowerMock、Spock等等,SpringBoot默认的Mock框架是Mockito,和junit一样,只需要依赖spring-boot-starter-test就可以。
例如:import static org.mockito.Mockito.*;
//创建mock对象,mock一个List接口
List mockedList = mock(List.class);
//如果不使用静态导入,则必须使用Mockito调用
List mockList = Mockito.mock(List.class);
//你可以mock一个具体的类型,而不仅是接口
LinkedList mockedList = mock(LinkedList.class);
mockedList.add("one");
//验证
verify(mockedList).add("one");
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());
当调用mockList.get(0)的时候,返回first
当调用mockList.get(1)的时候,抛出一个运行时异常