Flutter:测试是否抛出特定异常

xpe*_*dev 9 dart flutter flutter-test

简而言之,throwsA(anything)用dart进行单元测试不足以满足我的需求。如何测试特定的错误消息或类型

这是我要捕获的错误:

class MyCustErr implements Exception {
  String term;

  String errMsg() => 'You have already added a container with the id 
  $term. Duplicates are not allowed';

  MyCustErr({this.term});
}
Run Code Online (Sandbox Code Playgroud)

这是当前通过的断言,但是要检查上面的错误类型:

expect(() => operations.lookupOrderDetails(), throwsA(anything));

这就是我想做的:

expect(() => operations.lookupOrderDetails(), throwsA(MyCustErr));

Ber*_*Ber 14

在 Flutter 1.12.1 中不推荐使用 `TypeMatcher<>' 之后,我发现它可以工作:

expect(() => operations.lookupOrderDetails(), throwsA(isInstanceOf<MyCustErr>()));
Run Code Online (Sandbox Code Playgroud)

  • `isInstanceOf` 也已被弃用,取而代之的是 `isA`。所以代码现在应该是“expect(() =&gt; Operations.lookupOrderDetails(), throwsA(isA&lt;MyCustErr&gt;()));” (4认同)

Bre*_*ton 8

截至 2021 年 4 月,这是正确的方法。

正确的方法

import 'package:dcli/dcli.dart';
import 'package:test/test.dart';

 /// GOOD: works in all circumstances.
 expect(() => restoreFile(file), throwsA(isA<RestoreFileException>()));
Run Code Online (Sandbox Code Playgroud)

一些例子显示:

方法不正确

import 'package:dcli/dcli.dart';
import 'package:test/test.dart';
 /// BAD: works but not in all circumstances
 expect(restoreFile(file), throwsA(isA<RestoreFileException>()));
Run Code Online (Sandbox Code Playgroud)

注意在期望之后缺少的 '() => '。

不同之处在于第一种方法适用于返回 void 的函数,而第二种方法则不能。

所以第一种方法应该是首选技术。

要测试特定的错误消息:

检查异常内容

import 'package:dcli/dcli.dart';
import 'package:test/test.dart';

    expect(
        () => copy(from, to),
        throwsA(predicate((e) =>
            e is CopyException &&
            e.message == 'The from file ${truepath(from)} does not exists.')));
Run Code Online (Sandbox Code Playgroud)


Gün*_*uer 5

这应该做您想要的:

expect(() => operations.lookupOrderDetails(), throwsA(const TypeMatcher<MyCustErr>()));

expect(() => operations.lookupOrderDetails(), isInstanceOf<MyCustErr>());
Run Code Online (Sandbox Code Playgroud)

如果您只想检查异常,请检查以下答案

  • 作为对未来人们的提醒,我无法找到第一个工作替代方案。我发现这是因为 VS Code Intellisense 让我导入 `'package:flutter/{widgets-material-cupertino}.dart'` 当你实际上想要导入 `'package:matcher/matcher.dart'` 时。 (3认同)
  • 那对我没有用。也许是由于我的设置:```预期:&lt;MyCustErr的实例&gt;实际:&lt;Closure:()=&gt; dynamic&gt;```删除闭包也不起作用 (2认同)
  • nossir它不是对我有用,但只要我有其他选择即可。谢谢! (2认同)
  • 从 Flutter 1.12.1 开始,TypeMatcher&lt;&gt; 已被弃用。对我来说,这个匹配器有效:`throwsA(isInstanceOf&lt;MyCustErr&gt;())` (2认同)
  • `TypeMatcher` 和 `isInstanceOf` 均已被弃用。请改用 throwsA(isA&lt;MyCustErr&gt;())`。 (2认同)