前言:前面讲了java的单测框架,但是遇到依赖了很多外部环境的方法就得考虑使用Mock框架了。
为什么需要mock?它与junit什么关系?
在做单元测试的时候,我们会发现我们要测试的方法会引用很多外部依赖的对象,比如:(发送邮件,网络通讯,记录Log, 文件系统 之类的)。 而我们没法控制这些外部依赖的对象。 为了解决这个问题,我们需要用到Stub和Mock来模拟这些外部依赖的对象,从而控制它们。
JUnit是单元测试框架,可以轻松的完成关联依赖关系少或者比较简单的类的单元测试,但是对于关联到其它比较复杂的类或对运行环境有要求的类的单元测试,模拟环境或者配置环境会非常耗时,实施单元测试比较困难。而这些“mock框架”(Mockito 、jmock 、 powermock、EasyMock),可以通过mock框架模拟一个对象的行为,从而隔离开我们不关心的其他对象,使得测试变得简单。(例如service调用dao,即service依赖dao,我们可以通过mock dao来模拟真实的dao调用,从而能达到测试service的目的。)
模拟对象(Mock Object)可以取代真实对象的位置,用于测试一些与真实对象进行交互或依赖于真实对象的功能,模拟对象的背后目的就是创建一个轻量级的、可控制的对象来代替测试中需要的真实对象,模拟真实对象的行为和功能。
使用Mock通常会带来以下一些好处:
- 隔绝其他模块出错引起本模块的测试错误
- 隔绝其他模块的开发状态,只要定义好接口,不用管他们开发有没有完成
- 一些速度较慢的操作,可以用Mock Object代替,使单测快速返回
- 隔离环境对单测执行的影响,实现在没有外部服务时也能运行单测
Mock框架
常见的Mock框架有EasyMock、Mocktio、JMockit、PowerMock等。
关于Mocktio的使用可以参考文档:
[https://static.javadoc.io/org.mockito/mockito-core/2.7.22/org/mockito/Mockito.html
https://juejin.im/entry/578f11aec4c971005e0caf82]
(https://static.javadoc.io/org.mockito/mockito-core/2.7.22/org/mockito/Mockito.html
https://juejin.im/entry/578f11aec4c971005e0caf82)
当Mockito的注解使用起来比较方便,具体注解的使用参见前面链接的文档,Mockito处理注解是通过MockitoAnnotations.initMocks(target)来处理的,而Mockito提供的Runner和Rule其实就是简单的在单测方法执行前执行该行代码,所以可以通过 @RunWith(MockitoJUnitRunner.class)或@Rule public MockitoRule mockitoRule = MockitoJUnit.rule()方式来使用Mockito注解功能,当和Spring Test一起使用时,因为一般会使用Spring的Runner,所以可以通过Rule的方式来使用Mockito的注解功能。