diff --git a/docs/zh-cn/doc/comparation.md b/docs/zh-cn/doc/comparation.md index bde16ce..05acdcf 100644 --- a/docs/zh-cn/doc/comparation.md +++ b/docs/zh-cn/doc/comparation.md @@ -1,15 +1,26 @@ 主流Mock工具对比 --- -除`TestableMock`外,目前主要的Mock工具主要有`Mockito`、`PowerMock`和`JMockit`,基本差异如下: +除`TestableMock`外,目前主要的Mock工具主要有`Mockito`、`Spock`、`PowerMock`和`JMockit`,基本差异如下: | 工具 | 原理 | 最小Mock单元 | 对被Mock方法的限制 | 上手难度 | IDE支持 | | ---- | ---- | ---- | ---- | ---- | ---- | | Mockito | 动态代理 | 类 | 不能Mock私有/静态和构造方法 | **较容易** | **很好** | -| PowerMock | 自定义类加载器 | 类 | **任何方法皆可** | 较繁琐 | **较好** | -| JMockit | 运行时字节码修改 | 类 | 不能Mock构造方法(new操作符) | 较繁琐 | 一般 | +| 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`是一款功能性与易用性均居于`Mockito`与`PowerMock`之间的Mock工具,较好的弥补了两者各自的不足。该项目在2017年尝试推出JMockit2重写版本但未能完成,目前处于不活跃的维护状态。 + 相比之下,`TestabledMock`的功能与`PowerMock`基本平齐,且极易上手,只需掌握`@MockMethod`注解就可以完成绝大多数任务。 当前`TestableMock`的主要不足在于,编写Mock方法时IDE尚无法即时提示方法参数是否正确匹配。若发现匹配效果不符合预期,需要通过[自助问题排查](zh-cn/doc/troubleshooting.md)文档提供的方法在运行期进行校验。这个功能未来需要通过扩展主流IDE插件来提供。 + +此外,由于`TestableMock`独辟蹊径的采用基于单个方法的Mock机制,将Mock方法定义与单元测试用例解耦,一方面使得Mock方法具有默认可复用性,单元测试用例也因此变得更干净纯粹,另一方面也导致Mock方法定义变得零散,生命周期管理起来相对困难,对现有开发者的Mock编写习惯会带来一定改变。 diff --git a/docs/zh-cn/doc/frequency-asked-questions.md b/docs/zh-cn/doc/frequently-asked-questions.md similarity index 92% rename from docs/zh-cn/doc/frequency-asked-questions.md rename to docs/zh-cn/doc/frequently-asked-questions.md index 09a648a..6967cc7 100644 --- a/docs/zh-cn/doc/frequency-asked-questions.md +++ b/docs/zh-cn/doc/frequently-asked-questions.md @@ -37,7 +37,7 @@ Kotlin语言中的`String`类型实际上是`kotlin.String`,而非`java.lang.S #### 6. 在IntelliJ IDE中运行单个测试用例时,用了`@EnablePrivateAccess`注解还是报私有成员访问错误? -IntelliJ的默认编译方法跳过了`JSR-269`规范的注解处理器,在IntelliJ系统配置的"Build Tools > Maven > Runner"中开启"Delegate IDE build/run actions to maven"选项即可: +IntelliJ默认编译方法对`JSR-269`规范注解处理器的处理机制与Maven标准不完全兼容,在IntelliJ系统配置的"Build Tools > Maven > Runner"中开启"Delegate IDE build/run actions to maven"选项即可: ![delegate-ide-build-to-maven](https://testable-code.oss-cn-beijing.aliyuncs.com/delegate-ide-build-to-maven.png) diff --git a/docs/zh-cn/doc/invoke-matcher.md b/docs/zh-cn/doc/invoke-matcher.md index ebec4e9..ef9a81f 100644 --- a/docs/zh-cn/doc/invoke-matcher.md +++ b/docs/zh-cn/doc/invoke-matcher.md @@ -3,7 +3,7 @@ 在测试中,除了需要将某些含有外部依赖的方法替换为Mock,经常还会需要验证该方法被调用时的参数是否符合预期。 -在TestableMock中提供了校验器(verifier)和匹配器(matcher)来实现这一功能。譬如: +在`TestableMock`中提供了校验器(verifier)和匹配器(matcher)来实现这一功能。譬如: ```java @Test @@ -15,7 +15,7 @@ public test_case() { 这个用例会检查在执行被测方法`methodToTest()`时,名称是`mockMethod`的Mock方法是否有被调用过,且调用时收到的参数值是否为`123`和`"abc"`(假设被Mock的`mockMethod`方法有两个参数)。 -除了这种简单校验以外,TestableMock当前已经支持了多种**校验器**,以及能够模糊匹配参数特征的**匹配器**。 +除了这种简单校验以外,`TestableMock`当前已经支持了多种**校验器**,以及能够模糊匹配参数特征的**匹配器**。 在示例项目`java-demo`和`kotlin-demo`中的`DemoMatcherTest`测试类详细展示了这些校验器和匹配器的用法。 diff --git a/docs/zh-cn/doc/use-mock.md b/docs/zh-cn/doc/use-mock.md index 466e723..e5917f7 100644 --- a/docs/zh-cn/doc/use-mock.md +++ b/docs/zh-cn/doc/use-mock.md @@ -7,6 +7,8 @@ > - Mock非构造方法,拷贝原方法定义到测试类,增加一个与调用者类型相同的参数,加`@MockMethod`注解 > - Mock构造方法,拷贝原方法定义到测试类,返回值换成构造的类型,方法名随意,加`@MockContructor`注解 +> **注意**:当前版本还有一项约定是,测试类名称应该为`被测类名+Test`,通常Java单元测试均符合这种惯例。此约定在未来的`TestableMock`版本中可能会被放宽或去除。 + 具体的Mock方法定义约定如下: #### 1. 覆写任意类的方法调用 @@ -105,6 +107,8 @@ private BlackBox createBlackBox(String text) { 在Mock方法中可以通过`TestableTool.TEST_CASE`和`TestableTool.SOURCE_METHOD`来识别**当前运行的测试用例名称**和**进入该Mock方法前的被测类方法名称**,从而区分处理不同的调用场景。 +> 这两个字段的实现机制基于调用堆栈分析,尽管已经做了各种特殊情况的处理,但在涉及多线程的复杂场景下,依然存在误判的可能。若您发现了相关的可复现BUG,请在Github提交Issue。 + 完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_get_source_method_name()`和`should_able_to_get_test_case_name()`测试用例。 #### 6. 验证Mock方法被调用的顺序和参数 diff --git a/docs/zh-cn/sidebar.md b/docs/zh-cn/sidebar.md index 92e8559..0628503 100644 --- a/docs/zh-cn/sidebar.md +++ b/docs/zh-cn/sidebar.md @@ -6,7 +6,7 @@ - 使用参考 - [校验Mock调用](zh-cn/doc/invoke-matcher.md) - - [常见使用问题](zh-cn/doc/frequency-asked-questions.md) + - [常见使用问题](zh-cn/doc/frequently-asked-questions.md) - [自助问题排查](zh-cn/doc/troubleshooting.md) - [Testable Maven插件](zh-cn/doc/use-maven-plugin.md)