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

使用mocktail单元测试:类型错误与方法调用验证问题

问题分析与解决

第一个错误:type 'Null' is not a subtype of type 'Future<void>'

你犯了两个没必要的操作:

  1. 给真实的Repository实例的somethingFancy方法加when stub,这完全多余——真实的somethingFancy本来就会执行内部逻辑,不需要用mocktail去拦截它。
  2. 没给MockService的doSomething方法做stub,mocktail的Mock类默认返回null,但doSomething的返回类型是Future<void>,null无法匹配这个类型,所以抛出类型错误。

第二个错误:no matching calls

当你换成MockRepository时,这个mock类的somethingFancy是mock实现,默认不会执行真实逻辑(也就是不会调用service.doSomething),所以service的方法根本没被触发,自然verify不到任何调用。

正确的测试写法

直接用真实的Repository,传入MockService,只需要stubMockService的方法,然后执行repository的方法,最后verify service的方法是否被调用:

class MockService extends Mock implements Service {}

class Repository {
  Repository({
    required this.service,
  });
  final Service service;

  Future<void> somethingFancy() async {
    await service.doSomething();
  }
}

class Service {
  Future<void> doSomething() async {}
}

void main() {
  final service = MockService();
  final repository = Repository(service: service);

  group('auth repository test', () {
    test('test name', () async {
      // 只需要stub MockService的doSomething方法,让它返回合法的Future<void>
      when(() => service.doSomething()).thenAnswer((_) => Future.value());
      
      // 调用真实repository的方法
      await repository.somethingFancy();

      // 验证service的方法是否被调用了一次
      verify(() => service.doSomething()).called(1);
    });
  });
}

关键点:

  • 测试Repository的逻辑时,用真实的Repository实例,依赖的Service用Mock替代。
  • 只需要给Mock的依赖(这里是Service)做stub,确保它的方法返回合法的类型。
  • when和verify的参数要传方法调用的lambda表达式(() => service.doSomething()),而不是直接传方法引用(service.doSomething),这是mocktail的正确用法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:05:34