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

Dart Mockito 如何实现Mock对象可设置字段的存根与校验

Mockito Mock属性读写存根配置方案

问题复现

使用Mockito编写测试时遇到互斥问题:

  1. setUp阶段编写固定存根when(mockStore.formType).thenReturn(const Edit())时,后续修改mockStore.formType取值永远返回固定的Edit()实例,测试断言失败
  2. 移除上述固定存根后,调用mockStore.formType会直接抛出缺失存根错误

相关代码如下:
测试初始化代码:

group("VgnItmFormEvents", () {
  setUp(() {
    mockStore = MockManageVgnItmStore();
    when(mockStore.formType).thenReturn(const Edit());// 若移除该行则会抛出缺失存根错误
})

失败的测试用例:

test('OnNameChanged', () async {
  mockStore.formType = Add(name: 'add');
  expect(mockStore.formType, Add(name: 'add'));
});

真实业务对象的字段实现:

// Store类中对应实现
FormType get formType => stateNotifiersVm.formType;
set formType(FormType formType) =>
    stateNotifiersVm.formTypeStateNotifier.setState(formType);
// stateNotifiersVm中对应实现
FormType get formType => _formType;
set formType(FormType formType) => formTypeStateNotifier.setState(formType);

根因

Mockito默认生成的Mock类不会自动处理属性的setter逻辑,getter返回值完全由when声明的存根规则决定,写死固定返回值后,set操作不会对getter的返回结果产生任何影响。

解决方法

不要给getter写死固定返回值,在测试上下文中维护一个局部变量存储属性值,同时给getter、setter分别配置存根逻辑,模拟真实属性的读写行为:

group("VgnItmFormEvents", () {
  late MockManageVgnItmStore mockStore;
  setUp(() {
    mockStore = MockManageVgnItmStore();
    // 初始化属性默认值,和原逻辑默认返回Edit()对齐
    FormType currentFormType = const Edit();

    // 存根getter:每次读取返回变量存储的最新值
    when(mockStore.formType).thenAnswer((_) => currentFormType);

    // 存根setter:赋值时更新内部存储的变量值
    when(() => mockStore.formType = any()).thenAnswer((invocation) {
      currentFormType = invocation.positionalArguments.first as FormType;
    });
  });

  test('OnNameChanged', () async {
    mockStore.formType = Add(name: 'add');
    // 此时读取到的是赋值后的最新值,断言正常通过
    expect(mockStore.formType, Add(name: 'add'));
  });
});

该配置同时解决两个问题:

  • 初始阶段getter有合法存根,不会抛出缺失存根错误
  • setter调用会同步更新内部存储的值,getter始终返回最新赋值结果,支持对赋值后的值做断言校验

内容的提问来源于stack exchange,提问作者BeniaminoBaggins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:36:25