Dart通过Mockito捕获Mock属性测试私有方法的实现
Dart 单测捕获私有方法引用的无侵入实现
场景说明
现有业务代码存在类私有方法,类初始化时会将该私有方法的引用赋值给关联Perk实例的jump属性:
class Monkey{ final name; final Perk _perk; Monkey('Maya', this._perk){ this._perk.jump = this._jump; } void _jump(int a){ // 待测试的私有方法 print('jump ${a}'); } }
已完成的测试准备
- 基于Mockito封装Mock类:
class MockPerk extends Mock implements Perk{}
测试目标
- 传入MockPerk实例完成Monkey对象构造
- 捕获
_perk.jump被赋值时传入的内容 - 获取Monkey私有
_jump的方法引用,完成方法逻辑校验
测试约束
- 不允许修改原有业务代码,将私有方法改为公有方法
- 不允许使用
@visibleForTesting注解将私有方法开放为测试可访问的接口
实现方案
- 借助Mockito的setter捕获能力获取方法引用
测试文件中定义临时变量存储捕获到的引用,对jump属性的setter做存根,当构造函数触发属性赋值时,直接将传入的方法引用存入临时变量,全程不需要改动业务代码。 - 具体测试代码:
// 临时变量存储捕获到的_jump方法引用 late void Function(int) capturedJumpRef; test('校验Monkey私有_jump方法逻辑', () { final mockPerk = MockPerk(); // 为jump的setter添加捕获逻辑 when(mockPerk.jump = captureAny).thenAnswer((invocation) { capturedJumpRef = invocation.positionalArguments.first as void Function(int); }); // 触发Monkey构造流程,完成方法引用的传递 Monkey('Maya', mockPerk); // 直接调用捕获的方法引用,即可完成对原私有方法的全量校验 // 可模拟不同入参、校验方法副作用、验证输出逻辑等 capturedJumpRef(5); });
- 实现原理
该方案完全不依赖Dart的私有成员访问权限突破,获取到的是业务流程正常传递给Perk实例的函数引用,和原_jump方法属于同一个内存地址,执行逻辑和直接调用私有方法完全一致,不会引入测试侧的逻辑偏差。
内容的提问来源于stack exchange,提问作者Ensei Tankado
相关产品推荐
相关产品推荐

