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

Flutter Mocktail测试:如何捕获未在when方法中抛出的异常?

Flutter Mocktail测试:如何捕获未在when方法中抛出的异常?

嘿,我来帮你搞定这个测试里的异常捕获问题~

你现在遇到的核心问题是:makeRequest 方法会在仓库返回null时主动抛出异常,但测试里直接await这个方法的话,异常会直接导致测试失败——因为测试框架没收到「我们预期这个异常抛出」的信号。下面给你两种靠谱的解决办法:

方法一:用expectLater验证异常抛出(推荐)

这是Flutter测试框架官方推荐的异步异常验证方式,它会等待异步操作完成,并检查是否抛出了预期的异常:

test('When api returns null, should throw exception', () async {
  // stub
  when(() => repository.get(requestParams))
      .thenAnswer((_) => Future.value(null));

  // 验证方法会抛出指定类型的异常
  await expectLater(
    () => usecase.makeRequest(requestParams),
    throwsA(isA<Exception>()),
  );

  // 验证仓库方法确实被调用了一次
  verify(() => repository.get(requestParams)).called(1);
});

这种方式最简洁,而且能清晰表达测试意图:我们就是要确认这个方法在仓库返回null时会抛出异常。

方法二:手动用try-catch捕获异常(适合检查异常细节)

如果你还想验证异常的具体内容(比如错误消息是不是"Whoops"),可以用try-catch手动捕获后再做断言:

test('When api returns null, should throw exception', () async {
  // stub
  when(() => repository.get(requestParams))
      .thenAnswer((_) => Future.value(null));

  Exception? caughtException;
  try {
    await usecase.makeRequest(requestParams);
  } catch (e) {
    caughtException = e as Exception;
  }

  // 断言异常确实被捕获到,且错误消息符合预期
  expect(caughtException, isNotNull);
  expect(caughtException?.toString(), contains('Whoops'));

  // 验证仓库方法的调用次数
  verify(() => repository.get(requestParams)).called(1);
});

为什么原来的代码会失败?

你之前直接await usecase.makeRequest(requestParams),当方法抛出异常时,测试框架会把这个未捕获的异常当成测试错误,而不是预期行为。所以必须通过上述方式明确告诉测试框架:这个异常是我们故意要验证的结果。

备注:内容来源于stack exchange,提问作者José Carlos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 10:12:57