testable-mock/docs/zh-cn/doc/comparation.md
2022-02-05 21:28:28 +08:00

3.4 KiB
Raw Blame History

主流Mock工具对比

TestableMock目前主要的Mock工具主要有MockitoSpockPowerMockJMockit,基本差异如下:

工具 原理 最小Mock单元 对被Mock方法的限制 上手难度 IDE支持
Mockito 动态代理 不能Mock私有/静态和构造方法 较容易 很好
Spock 动态代理 不能Mock私有/静态和构造方法 较复杂 一般
PowerMock 自定义类加载器 任何方法皆可 较复杂 较好
JMockit 运行时字节码修改 不能Mock构造方法(new操作符) 较复杂 一般
TestableMock 运行时字节码修改 方法 任何方法皆可 较容易 较好

Mockito是Java最老牌的Mock工具稳定性和易用性较好IntelliJ和Eclipse都有专用插件支持。相对不足之处在于Mock功能稍弱在必要情况下需与其他Mock工具配合使用。

Spock是一款代码可读性非常高的单元测试框架内置Mock支持具有很好的整体感。由于同样基于动态代理实现其不足点与Mockito类似。

PowerMock是一款功能十分强大的Mock工具其基本语法与Mockito兼容,同时扩展了许多Mockito缺失的功能包括对支持对私有、静态和构造方法实施Mock。但由于使用了自定义类加载器会导致Jacoco在默认的on-the-fly模式下覆盖率跌零。

JMockit是一款功能性与易用性均居于MockitoPowerMock之间的Mock工具较好的弥补了两者各自的不足。该项目在2017年尝试推出JMockit2重写版本但未能完成目前处于不活跃的维护状态。

相比之下,TestabledMock的功能与PowerMock基本平齐,且极易上手,只需掌握一个@MockInvoke注解就可以完成绝大多数Mock操作。

TestableMock的不足

为了便于开发者进行Mock工具的合理选型我们认为客观的强调TestabledMock存在的不足,与阐述它的优点同样重要。

任何事物都有两面性。由于TestableMock独辟蹊径采用“每个业务类拥有一个专属Mock容器类”的思维方式将Mock方法定义与单元测试用例解耦一方面使得Mock方法具有默认可复用性单元测试用例也因此变得更干净纯粹另一方面也导致Mock方法定义变得零散生命周期管理起来相对困难对现有开发者的Mock编写习惯会带来一定改变。

此外,TestableMock最初的设计主要面向标准单元测试场景(每个类有自己的测试用例,测试类与被测类基本逐一对应)。为了最大限度的提升易用性,把需要用到的注解、操作步骤都减少到最少,TestableMock采用了许多“约定优于配置”的设计。譬如被测量、测试类与Mock容器类在同一包路径且分别按约定命名等。对于单元测试较规范的项目而言TestableMock将极大降低Mock引入的成本对于规范不足的项目依然可以结合@MockWith、包路径映射等功能完成相同的Mock效果但应当尤其注意这些“花哨”的功能对代码可读性和可维护性带来的负面影响。