读 8658
前言
Mockito
是当前最流行的 单元测试 Mock
框架。采用 Mock
框架,我们可以 虚拟 出一个 外部依赖,降低测试 组件 之间的 耦合度,只注重代码的 流程与结果,真正地实现测试目的。
正文
什么是Mock
Mock
的中文译为仿制的,模拟的,虚假的。对于测试框架来说,即构造出一个模拟/虚假的对象,使我们的测试能顺利进行下去。
Mock
测试就是在测试过程中,对于某些 不容易构造(如 HttpServletRequest
必须在 Servlet
容器中才能构造出来)或者不容易获取 比较复杂 的对象(如 JDBC
中的 ResultSet
对象),用一个 虚拟 的对象(Mock
对象)来创建,以便测试方法。
为什么使用Mock测试
单元测试 是为了验证我们的代码运行正确性,我们注重的是代码的流程以及结果的正确与否。
对比真实运行代码,可能其中有一些 外部依赖 的构建步骤相对麻烦,如果我们还是按照真实代码的构建规则构造出外部依赖,会大大增加单元测试的工作,代码也会参杂太多非测试部分的内容,测试用例显得复杂难懂。
采用 Mock
框架,我们可以 虚拟 出一个 外部依赖,只注重代码的 流程与结果,真正地实现测试目的。
Mock测试框架的好处
- 可以很简单的虚拟出一个复杂对象(比如虚拟出一个接口的实现类);
- 可以配置
mock
对象的行为; - 可以使测试用例只注重测试流程与结果;
- 减少外部类、系统和依赖给单元测试带来的耦合。
Mockito的流程
如图所示,使用 Mockito
的大致流程如下:
-
创建 外部依赖 的
Mock
对象, 然后将此Mock
对象注入到 测试类 中; -
执行 测试代码;
-
校验 测试代码 是否执行正确。
Mockito的使用
在 Module
的 build.gradle
中添加如下内容:
dependencies {
//Mockito for unit tests
testImplementation "org.mockito:mockito-core:2.+"
//Mockito for Android tests
androidTestImplementation 'org.mockito:mockito-android:2.+'
}
这里稍微解释下:
mockito-core
: 用于 本地单元测试,其测试代码路径位于module-name/src/test/java/
mockito-android
: 用于 设备测试,即需要运行android
设备进行测试,其测试代码路径位于module-name/src/androidTest/java/
mockito-core最新版本可以在 Maven 中查询:mockito-core。 mockito-android最新版本可以在 Maven 中查询:mockito-android
Mockito的使用示例
普通单元测试使用 mockito(mockito-core)
,路径:module-name/src/test/java/
这里摘用官网的 Demo
:
检验调对象相关行为是否被调用
import static org.mockito.Mockito.*;
// Mock creation
List mockedList = mock(List.class);
// Use mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one"); //调用了add("one")行为
mockedList.clear(); //调用了clear()行为
// Selective, explicit, highly readable verification
verify(mockedList).add("one"); // 检验add("one")是否已被调用
verify(mockedList).clear(); // 检验clear()是否已被调用
这里 mock
了一个 List
(这里只是为了用作 Demo
示例,通常对于 List
这种简单的类对象创建而言,直接 new
一个真实的对象即可,无需进行 mock
),verify()
会检验对象是否在前面已经执行了相关行为,这里 mockedList
在 verify
之前已经执行了 add("one")
和 clear()
行为,所以verify()
会通过。
配置/方法行为
// you can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");
// th