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

2.6 KiB
Raw Blame History

Mock的生效范围

@MockInvoke@MockNew注解上都有一个scope参数,其可选值有两种

  • MockScope.GLOBAL该Mock方法将全局生效
  • MockScope.ASSOCIATED该Mock方法仅对Mock容器关联测试类中的测试用例生效

对于常规项目而言单元测试里需要被Mock的调用都是由于其中包含了不需要或不便于测试的逻辑譬如“依赖外部系统”、“包含随机结果”、“执行非常耗时”等等这类调用在整个单元测试的生命周期里都应该被Mock方法置换不论调用的发起者是谁。因此TestableMock默认所有Mock方法都是全局生效的scope默认值为MockScope.GLOBAL

举例来说,CookerServiceSellerService是两个需要被测试的类,假设CookerService的代码里的hireXxx()cookXxx()方法都需要依赖外部系统。因此在进行单元测试时,开发者在CookerService关联的Mock容器里使用@MockInvoke注解定义了这些调用的替代方法。

此时若该Mock方法的scope值为MockScope.GLOBAL,则不论是在SellerServiceTest测试类还是在CookerServiceTest测试类的测试用例只要直接或间接的执行到这行调用都会被置换为调用Mock方法。若该Mock方法的scope值为MockScope.ASSOCIATED则Mock只对CookerServiceTest类中的测试用例生效,而SellerServiceTest类中的测试用例在运行过程中执行到了CookerService类的相关代码,将会执行原本的调用。

参见Java和Kotlin示例中SellerServiceTest测试类的用例。

在一些大型项目中会有“下层模块编写单元测试上层模块编写端到端集成测试两者混合在一起运行”的情况这时候大部分Mock方法都应该使用MockScope.ASSOCIATED作为生效范围。针对这种情况,TestableMock支持通过mock.scope.default运行参数来修改默认的Mock方法生效范围详见全局运行参数文档。

特别说明。若要Mock静态块里的调用Mock方法的scope必须为MockScope.GLOBAL因为静态块中的代码在程序初始化时就会执行不属于任何测试用例。典型场景是在使用JNI开发的项目中Mock系统库的加载方法。

static {
    System.loadLibrary("native-lib");
}

若默认的scope参数不是MockScope.GLOBAL则相应Mock方法应当显式的声明scope值,例如:

@MockInvoke(targetClass = System.class, scope = MockScope.GLOBAL)
private void loadLibrary(String libname) {
    System.err.println("loadLibrary " + libname);
}