本文主要讲利用mockito框架的单元测试流程,具体的mockito代码部分放在下篇介绍。
1.1 单元测试的目的
单元测试的思路是在不涉及依赖关系的情况下测试代码(隔离性),所以测试代码与其他类或者系统的关系应该尽量被消除。
一个可行的消除方法就是替换掉依赖类(测试替换),也就是我们可以使用替身来替换掉真正的依赖对象。
1.2 引子
在测试过程中,对于某些不容易构造(如httpservletrequest必须在servlet容器中才能构建出来)或者不容易获取比较复杂的对象(如JDBC中的resultset对象),用一个虚拟的对象mock对象来创建以便测试的测试方法。
mock最大的功能就是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。
下面2个图可以很好的说明mock的作用:
1.3 Mockito的特性
Mockito 是Java 单元测试 Mock 框架, 开源 。
大多 Java Mock 库如 EasyMock 或 JMock 都是 expect-run-verify (期望-运行-验证)方式,而 Mockito 则使用更简单,更直观的方法:在执行后的互动中提问。使用 Mockito,你可以 验证任何你想要的 。而那些使用 expect-run-verify 方式的库,你常常被迫查看无关的交互。
非 expect-run-verify 方式 也意味着,Mockito 无需准备昂贵的前期启动。他们的目标是透明的,让开发人员专注于测试选定的行为。
Mockito 拥有的非常少的 API,所有开始使用 Mockito,几乎没有时间成本。因为只有一种创造 mock 的方式。只要记住,在执行前 stub,而后在交互中验证。你很快就会发现这样 TDD java 代码是多么自然。
类似 EasyMock 的语法 来的,所以你可以放心地重构。Mockito 并不需要“expectation(期望)”的概念。只有 stub 和验证。
Mockito 实现了 Gerard Meszaros 所谓的 Test Spy.
其他的一些特点:
- 可以 mock 具体类而不单止是接口
- 一点注解语法糖 - @Mock
- 干净的验证错误是 - 点击堆栈跟踪,看看在测试中的失败验证;点击异常的原因来导航到代码中的实际互动。堆栈跟踪总是干干净净。
- 允许灵活有序的验证(例如:你任意有序 verify ,而不是每一个单独的交互)
- 支持“详细的用户号码的时间”以及“至少一 次”验证
- 灵活的验证或使用参数匹配器的 stub ( anyObject() , anyString() 或 refEq() 用于基于反射的相等匹配)
- 允许创建 自定义的参数匹配器 或者使用现有的 hamcrest 匹配器
1.4 使用Mockito进行单元测试的实例
1.4.1 环境准备
我这使用的是IntelliJ IDEA,构建工具:Maven.
先添加maven依赖:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.8.47</version>
</dependency>
添加jar包:
添加静态资源
import static org.mockito.Mockito.*;
编写测试代码
该章节,具体的哪一类型的代码,下篇文章详细分类介绍,本篇主要介绍流程。
@Test
public void TestMockito1(){
String word="mocked return";
Apple apple = Mockito.mock(Apple.class);
Mockito.when(apple.harvest(Mockito.anyString())).thenReturn(word);
Assert.assertEquals(apple.harvest("苹果收获啦"), word);
// Mockito.verify(apple.harvest("apple"));//验证函数执行是否经过了mock
}
1.5 编译
1.6 代码覆盖率
设置:
结果展示: