fix doc according to recent feedbacks

This commit is contained in:
金戟 2020-12-23 10:16:37 +08:00
parent 085c6784d4
commit 4701b3b42b
5 changed files with 22 additions and 7 deletions

View File

@ -1,15 +1,26 @@
主流Mock工具对比 主流Mock工具对比
--- ---
除`TestableMock`外目前主要的Mock工具主要有`Mockito`、`PowerMock`和`JMockit`,基本差异如下: 除`TestableMock`外目前主要的Mock工具主要有`Mockito`、`Spock`、`PowerMock`和`JMockit`,基本差异如下:
| 工具 | 原理 | 最小Mock单元 | 对被Mock方法的限制 | 上手难度 | IDE支持 | | 工具 | 原理 | 最小Mock单元 | 对被Mock方法的限制 | 上手难度 | IDE支持 |
| ---- | ---- | ---- | ---- | ---- | ---- | | ---- | ---- | ---- | ---- | ---- | ---- |
| Mockito | 动态代理 | 类 | 不能Mock私有/静态和构造方法 | **较容易** | **很好** | | Mockito | 动态代理 | 类 | 不能Mock私有/静态和构造方法 | **较容易** | **很好** |
| PowerMock | 自定义类加载器 | 类 | **任何方法皆可** | 较繁琐 | **较好** | | Spock | 动态代理 | 类 | 不能Mock私有/静态和构造方法 | 较复杂 | 一般 |
| JMockit | 运行时字节码修改 | 类 | 不能Mock构造方法(new操作符) | 较繁琐 | 一般 | | PowerMock | 自定义类加载器 | 类 | **任何方法皆可** | 较复杂 | **较好** |
| JMockit | 运行时字节码修改 | 类 | 不能Mock构造方法(new操作符) | 较复杂 | 一般 |
| TestableMock | 运行时字节码修改 | 方法 | **任何方法皆可** | **很容易** | 一般 | | 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`注解就可以完成绝大多数任务。 相比之下,`TestabledMock`的功能与`PowerMock`基本平齐,且极易上手,只需掌握`@MockMethod`注解就可以完成绝大多数任务。
当前`TestableMock`的主要不足在于编写Mock方法时IDE尚无法即时提示方法参数是否正确匹配。若发现匹配效果不符合预期需要通过[自助问题排查](zh-cn/doc/troubleshooting.md)文档提供的方法在运行期进行校验。这个功能未来需要通过扩展主流IDE插件来提供。 当前`TestableMock`的主要不足在于编写Mock方法时IDE尚无法即时提示方法参数是否正确匹配。若发现匹配效果不符合预期需要通过[自助问题排查](zh-cn/doc/troubleshooting.md)文档提供的方法在运行期进行校验。这个功能未来需要通过扩展主流IDE插件来提供。
此外,由于`TestableMock`独辟蹊径的采用基于单个方法的Mock机制将Mock方法定义与单元测试用例解耦一方面使得Mock方法具有默认可复用性单元测试用例也因此变得更干净纯粹另一方面也导致Mock方法定义变得零散生命周期管理起来相对困难对现有开发者的Mock编写习惯会带来一定改变。

View File

@ -37,7 +37,7 @@ Kotlin语言中的`String`类型实际上是`kotlin.String`,而非`java.lang.S
#### 6. 在IntelliJ IDE中运行单个测试用例时用了`@EnablePrivateAccess`注解还是报私有成员访问错误? #### 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) ![delegate-ide-build-to-maven](https://testable-code.oss-cn-beijing.aliyuncs.com/delegate-ide-build-to-maven.png)

View File

@ -3,7 +3,7 @@
在测试中除了需要将某些含有外部依赖的方法替换为Mock经常还会需要验证该方法被调用时的参数是否符合预期。 在测试中除了需要将某些含有外部依赖的方法替换为Mock经常还会需要验证该方法被调用时的参数是否符合预期。
在TestableMock中提供了校验器verifier和匹配器matcher来实现这一功能。譬如 `TestableMock`中提供了校验器verifier和匹配器matcher来实现这一功能。譬如
```java ```java
@Test @Test
@ -15,7 +15,7 @@ public test_case() {
这个用例会检查在执行被测方法`methodToTest()`时,名称是`mockMethod`的Mock方法是否有被调用过且调用时收到的参数值是否为`123`和`"abc"`假设被Mock的`mockMethod`方法有两个参数)。 这个用例会检查在执行被测方法`methodToTest()`时,名称是`mockMethod`的Mock方法是否有被调用过且调用时收到的参数值是否为`123`和`"abc"`假设被Mock的`mockMethod`方法有两个参数)。
除了这种简单校验以外TestableMock当前已经支持了多种**校验器**,以及能够模糊匹配参数特征的**匹配器**。 除了这种简单校验以外,`TestableMock`当前已经支持了多种**校验器**,以及能够模糊匹配参数特征的**匹配器**。
在示例项目`java-demo`和`kotlin-demo`中的`DemoMatcherTest`测试类详细展示了这些校验器和匹配器的用法。 在示例项目`java-demo`和`kotlin-demo`中的`DemoMatcherTest`测试类详细展示了这些校验器和匹配器的用法。

View File

@ -7,6 +7,8 @@
> - Mock非构造方法拷贝原方法定义到测试类增加一个与调用者类型相同的参数加`@MockMethod`注解 > - Mock非构造方法拷贝原方法定义到测试类增加一个与调用者类型相同的参数加`@MockMethod`注解
> - Mock构造方法拷贝原方法定义到测试类返回值换成构造的类型方法名随意加`@MockContructor`注解 > - Mock构造方法拷贝原方法定义到测试类返回值换成构造的类型方法名随意加`@MockContructor`注解
> **注意**:当前版本还有一项约定是,测试类名称应该为`被测类名+Test`通常Java单元测试均符合这种惯例。此约定在未来的`TestableMock`版本中可能会被放宽或去除。
具体的Mock方法定义约定如下 具体的Mock方法定义约定如下
#### 1. 覆写任意类的方法调用 #### 1. 覆写任意类的方法调用
@ -105,6 +107,8 @@ private BlackBox createBlackBox(String text) {
在Mock方法中可以通过`TestableTool.TEST_CASE`和`TestableTool.SOURCE_METHOD`来识别**当前运行的测试用例名称**和**进入该Mock方法前的被测类方法名称**,从而区分处理不同的调用场景。 在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()`测试用例。 完整代码示例见`java-demo`和`kotlin-demo`示例项目中的`should_able_to_get_source_method_name()`和`should_able_to_get_test_case_name()`测试用例。
#### 6. 验证Mock方法被调用的顺序和参数 #### 6. 验证Mock方法被调用的顺序和参数

View File

@ -6,7 +6,7 @@
- 使用参考 - 使用参考
- [校验Mock调用](zh-cn/doc/invoke-matcher.md) - [校验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) - [自助问题排查](zh-cn/doc/troubleshooting.md)
- [Testable Maven插件](zh-cn/doc/use-maven-plugin.md) - [Testable Maven插件](zh-cn/doc/use-maven-plugin.md)