软件测试-Mock
本文最后更新于:2021年5月27日 下午
什么是Mock
作为一个动词,mock
是模拟、模仿的意思
作为一个名词,mock
是指能够模仿真实对象行为的模拟对象
测试的对象一般称之为SUT(Software Under Test)
在软件测试中,它一定不是我们所测试的对象,而是 SUT 的依赖(dependency)。换句话说,mock 的作用是模拟 SUT 依赖对象的行为
此处被
Mock的作用
提高 SUT 的测试覆盖率
C 依赖 B,本质上依赖的是 B 的返回结果,也就是说 B 的返回结果会影响 C 的行为。通过 mock B 我们可以构造各种正常和异常的来自 B 的返回结果,从而更充分测试 C 的行为避免 B 的因素从而对 SUT 产生影响
依赖真实的 B 去测试 C 可能有很多问题:B 的开发没有完成时无法测试 C;B 有阻塞性bug 时无法测试 C;B 的依赖 C 有阻塞性 bug 时无法测试 C;提高 SUT 的测试效率
B 的真实行为可能很慢,而 B 的模拟行为是非常快的,因此可以加快 SUT 的测试执行速度
Mock的类型
方法级别 mock
mock 的对象是一个函数调用,例如获取系统环境变量类级别 mock:mock 的对象是一个类
例如一个 HTTP server接口级别 mock:mock 的对象是一个 API 接口
例如一个返回假数据的接口服务级别 mock:mock 的对象是整个服务
比如前端工程师自测试时,可以讲后端整个服务都 mock 掉,这其实等同于将后端的所有接口都 mock
打桩、调桩、Mock注入
在使用 mock 进行接口测试时,一般要做两件事情,即打桩和调桩
- 打桩:创建 mock 桩,指定 API 请求内容及其映射的 mock 响应内容
- 调桩:就是被测服务来请求 mock 桩并接收 mock 响应
- mock 注入(mock injection):用模拟桩来替换真实的依赖。阻断被测服务与真实服务之间的链路,建立被测服务与 mock 之间的链路过程
Mock注入方式
根据 mock 工作的位置,mock 可以分为 客户端 mock 和 服务端 mock
API 请求构造
- 客户端 mock:mock 在被测服务内部工作,直接拦截被测服务的 API 请求方法(比如 HTTP Client方法),在被测服务调用 API 请求方法时,直接从方法内部返回预定义的 mock 响应
- 服务端 mock:mock 在被测服务外部工作,作为 HTTP 服务器接收被测服务发送的 API 请求,并返回预定义的 mock 响应
客户端 mock 的注入其实就是改造被测服务的 API 请求方法,即在 API 请求方法中加入 mock 处理逻辑。当满足某些条件时执行 mock 分支,不满足时执行真实分
此种类型一般通过改造源码实现。优点:性能极好,缺点:实现成本较高
本地配置
对于服务端 mock,打桩之后会生成唯一的 mock 桩地址
被测服务拥有一个依赖服务地址配置项,在需要使用 mock 时将依赖服务地址修改成 mock 地址
优点:实现简单,缺点:不方便,进行 mock 服务与真实服务切换时需要修改配置项需要重启被测服务
反向代理
在微服务架构下,被测服务与依赖服务之间可能不是直连的,而是经过了一层反向代理,例如 API 网关。在这种情况下,被测服务是通过调用 API 网关来间接调用依赖服务的接口
在 API 网关模式下,mock 注入的具体做法就是修改 API 网关配置,将依赖服务 API 网关接口绑定的地址改成 mock 地址
优点:是对被测服务无侵入,并且实现更细粒度(接口级)的 mock
缺点:存在一定的时延
亚马逊 AWS 的 API 网关就是采用这种方式进行 mock
前向代理
服务端 mock 除了作为 HTTP 服务器,还可以兼备 HTTP 代理的功能,这种架构又叫做 mock 代理
,例如 mock server proxy
对于 mock 代理来说,它不仅能够返回 mock 响应,而且能够在需要的时候将 API 请求转发给依赖服务,并将依赖服务的真实响应返回给被测服务
使用前向代理模式,mock 注入的方式是将被测服务的依赖地址或网络代理修改为 mock 地址
优点:能够实现细粒度的 mock,并且能够根据录制的真实响应自动生成 mock
缺点:需要重启被测服务
常用 mock 工具
单元测试级别
这个级别的mock工具有 easymock、jMock、Mockito、Unitils Mock、PowerMock、JMockit等
接口测试级别
接口级别的mock工具完成的主要功能是对一个用户的请求,模拟server返回一个接口的响应数据
常用的有:Wiremock、Mockserver、Moco、Mock.js、RAP
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!