You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 07:36:03