testable-mock/docs/zh-cn/doc/scope-of-mock.md
2021-02-20 09:03:44 +08:00

27 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Mock的生效范围
---
在`@MockMethod`和`@MockConstructor`注解上都有一个`scope`参数,其可选值有两种
- `MockScope.GLOBAL`该Mock方法将全局生效
- `MockScope.ASSOCIATED`该Mock方法仅对Mock容器关联测试类中的测试用例生效
举例来说,`AaaService`和`BbbService`是两个需要被测试的类,在`BbbService`的代码里有个`recordTicket()`调用依赖外部系统。因此在进行单元测试时,开发者在`BbbService`关联的Mock容器里使用`@MockMethod`注解定义了这个调用的替代方法。此时若该Mock方法的`scope`值为`MockScope.GLOBAL`,则不论是在`AaaServiceTest`测试类还是在`BbbServiceTest`测试类的测试用例只要直接或间接的执行到这行调用都会被置换为调用Mock方法。若该Mock方法的`scope`值为`MockScope.ASSOCIATED`则Mock只对`BbbServiceTest`类中的测试用例生效,而`AaaServiceTest`类中的测试用例在运行过程中执行到了`BbbService`类的相关代码,将会执行`recordTicket()`的原本调用。
对于常规项目而言单元测试里需要被Mock的调用都是由于其中包含了不需要或不便于测试的逻辑譬如“依赖外部系统”、“包含随机结果”、“执行非常耗时”等等这类调用在整个单元测试的生命周期里都应该被Mock方法置换不论调用的发起者是谁。因此`TestableMock`默认所有Mock方法都是全局生效的即`scope`默认值为`MockScope.GLOBAL`。
在一些大型项目中会有“下层模块编写单元测试上层模块编写端到端集成测试两者混合在一起运行”的情况这时候大部分Mock方法都应该使用`MockScope.ASSOCIATED`作为生效范围。针对这种情况,`TestableMock`支持通过`mockScope`运行参数来修改默认的Mock方法生效范围详见[全局运行参数](zh-cn/doc/javaagent-args.md)文档。
> 特别说明。若要Mock静态块里的调用Mock方法的`scope`必须为`MockScope.GLOBAL`因为静态块中的代码在程序初始化时就会执行不属于任何测试用例。典型场景是在使用JNI开发的项目中Mock系统库的加载方法。
> ```java
> static {
> System.loadLibrary("native-lib");
> }
> ```
> 若默认的`scope`参数不是`MockScope.GLOBAL`则相应Mock方法应当显式的声明`scope`值,例如:
> ```java
> @MockMethod(targetClass = System.class, scope = MockScope.GLOBAL)
> private void loadLibrary(String libname) {
> System.err.println("loadLibrary " + libname);
> }
> ```