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

Flutter单元测试mocktail验证方法调用报非mock对象错误

错误原因

这个报错是三个问题共同导致的:

  • verify的回调写法错误:你写的() => repo.getResetPasswordToken只是获取了方法的引用(tear-off),没有传入参数实际调用该方法。mocktail的verify只能识别对mock对象方法的实际调用表达式,单纯拿方法引用不会被代理拦截,就会抛出Used on a non-mocktail object错误。
  • 测试逻辑缺失调用步骤:你在执行verify之前,根本没有主动调用过一次getResetPasswordToken方法,就算verify写法正确,调用计数也是0,无法匹配called(1)的预期。
  • 缺少方法返回值存根:mock对象的方法默认返回null,但你的getResetPasswordToken返回值是非空的Future类型,如果不提前设置存根返回合法值,调用方法时会直接抛出类型错误。
修改方案

按照以下步骤调整测试代码即可:

  1. 在测试执行前初始化mock对象,并用when给目标方法设置合法的测试返回值
  2. 在验证逻辑前,主动调用一次待测试的getResetPasswordToken方法
  3. 修正verify回调的写法,传入参数实际调用目标方法,不关心参数值时可以用any()做通配匹配

正确的测试代码示例:

import 'package:mocktail/mocktail.dart';
// 省略其他业务类导入

class RepoMock extends Mock implements Repository {}

void main() {
  late Repository repo;

  setUp(() {
    repo = RepoMock();
    // 给mock方法设置默认返回存根,避免非空类型报错
    when(() => repo.getResetPasswordToken(any()))
        .thenAnswer((_) async => /* 构造测试用的GraphQLResponse实例即可 */);
  });

  test("getResetPasswordToken调用验证", () {
    // 执行待验证的方法调用
    repo.getResetPasswordToken("test@example.com");
    // 验证方法被调用1次,这里必须传参实际调用方法
    verify(() => repo.getResetPasswordToken(any())).called(1);
  });
}

注意:如果方法的参数是你自定义的非Dart内置类型,需要提前调用registerFallbackValue(自定义类型的测试实例)注册fallback值,才能正常使用any()匹配参数,String、int这类内置类型不需要额外注册。

内容的提问来源于stack exchange,提问作者Cyrus the Great

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:12:36