Fan Lin

Results 91 comments of Fan Lin

用`PrivateAccessor.set()`方法可用修改私有或保护类型的成员变量,不论是本类定义的还是父类继承的

对`InnerUtilC.rawInfo()`方法的调用发生在`UtilB`类型中,因此需要在相应的`UtilBMock`类里创建Mock方法,`MethodAMock`类型的Mock定义不会生效

这个设计初衷是让每个类的开发者自己提供当前类内部的Mock调用,形成每个业务类对应一个单元测试类+一个单元Mock类的结构,这种Mock方式确实也是利弊各半,需要一定适应

正确。 `TestableMock`使用默认约定命名来简化配置,这种约定方式本身符合单元测试的最佳实践(测试类命名为被测类+Test,使用相同包路径),统一的单测规则有助于提高代码可读性和可维护性。 对于确实不符合约定的情况,也可以通过`@MockWith`等辅助注解来进行适配。

测试包路径不一致的问题应该可以用[包路径映射](https://alibaba.github.io/testable-mock/#/zh-cn/doc/use-package-mapping)的功能来解决,添加类似如下配置: ```properties mock.package.mapping.com.abc = com.abc.junit ``` 由于TestableMock设计时候主要考虑的是在“规范化”的单元测试中如何尽可能降低使用Mock的难度,非标准场景的单元测试确实是它的弱项。许多对于非标准情况的适配功能,包括包映射、MockWith等都是后来补充的,这些功能在一定程度上扩展了TestableMock的适用范围,但也带来了一些上手成本。 Mockito/PowerMockito的Mock粒度是整个类型,而TestableMock的Mock粒度是单个调用,从效果上原本就类似`spy`,即除非显示声明为Mock,否则默认是走正常业务逻辑,不需要有`spy(被测对象)`这样的声明。

不支持是指遇到什么问题呢?Mock没有生效,还是执行报错?

原理上是支持的。 可以参考[自助问题排查](https://alibaba.github.io/testable-mock/#/zh-cn/doc/troubleshooting)文档,查看一下实际调用的签名和Mock方法定义的签名是否由于某些原因未匹配上。

Testable的Mock的只会对Mock类自身关联的业务类生效。 对于 A.a() -> B.b() -> Util.s() 这样的调用链,如果希望Mock掉 b() 方法里的调用,则相应Mock方法需要放在 B 类型的Mock类里(比如`BTest.Mock`类型)。Mock类是与业务类关联而不是与测试用例关联,这一点和其他Mock框架有所不同。

目前没有实现这种功能。 两者实现思路不太一样,PowerMock是Mock被测类中的特定对象(以及对象中的所有方法),TestableMock是单独Mock被测类中的特定方法调用。从实现而言就是替换整个对象 vs 替换单个方法,这个差异使得TestableMock更加轻量,但无法做默认所有方法都是Mock这个功能,因为没有对象作为方法范围的边界。 理论上而言,TestableMock的机制能做到譬如“调用指定类型对象的所有方法默认换成Mock”的功能,近似于PowerMock的Mock对象。但这么做会使得Mock方法的生效逻辑变复杂,偏离简单易用的初衷。

对于明确是需要Mock某个对象的场景,Mockito、PowerMock的实现方式会更适合一些。 TestableMock也可以与Mockito共同使用,使用Mockito生成代理对象对象,作为Mock方法的返回值或是用于替换被测类中的成员对象。生成Mock对象方面的轮子在社区里已经比较多了,不太需要重新造。 单元测试通常应该在本地和测试环境运行,即使测试对象的方法全部是Mock的,也不建议连到线上环境跑测试,否则稍微疏忽就容易出大问题的。