你如何在Dart中对异常进行单元测试?

Sha*_*uli 27 dart

考虑一个函数,它根据传递的参数进行一些异常处理:

List range(start, stop) {
    if (start >= stop) {
      throw new ArgumentError("start must be less than stop");
    }
    // remainder of function
}
Run Code Online (Sandbox Code Playgroud)

如何测试是否引发了正确的异常?

Sha*_*uli 58

在这种情况下,有各种方法来测试异常.要简单地测试是否引发了异常:

expect(() => range(5, 5), throwsException);
Run Code Online (Sandbox Code Playgroud)

测试是否引发了正确的异常类型:

expect(() => range(5, 2), throwsA(TypeMatcher<IndexError>()));
Run Code Online (Sandbox Code Playgroud)

确保不会引发任何异常:

expect(() => range(5, 10), returnsNormally);
Run Code Online (Sandbox Code Playgroud)

测试异常类型和异常消息:

expect(() => range(5, 3), 
    throwsA(predicate((e) => e is ArgumentError && e.message == 'start must be less than stop')));
Run Code Online (Sandbox Code Playgroud)

这是另一种方法:

expect(() => range(5, 3), 
  throwsA(allOf(isArgumentError, predicate((e) => e.message == 'start must be less than stop'))));
Run Code Online (Sandbox Code Playgroud)

(感谢Google的Graham Wheeler提供的最后两个解决方案).

  • 看来使用 TypeMatcher 不再有效。有效的是 `throwsA(isA&lt;Exception&gt;())` (6认同)
  • 我正在做`expect(range(5,3),throwsArgumentError)`,但是没有在期望中捕获异常。期望的第一个参数必须是一个匿名函数,该函数最终将在调用时抛出。您的回答帮助我找到了这个愚蠢的错误,谢谢! (2认同)
  • 这绝对是最好的答案,但我想知道为什么对于这样一个简单的任务,语法必须如此冗长。 (2认同)

Hug*_*sos 7

作为@Shailen Tuli提议的更优雅的解决方案,如果您希望特定消息出现错误,您可以使用having.

在这种情况下,您正在寻找这样的东西:

expect(
  () => range(5, 3),
  throwsA(
    isA<ArgumentError>().having(
      (error) => error.message,        // The feature you want to check.
      'message',                       // The description of the feature.
      'start must be less than stop',  // The error message.
    ),
  ),
);
Run Code Online (Sandbox Code Playgroud)


Sha*_*ens 6

我喜欢这种方法:

test('when start > stop', () {
  try {
    range(5, 3);
  } on ArgumentError catch(e) {
    expect(e.message, 'start must be less than stop');
    return;
  }
  throw new ExpectException("Expected ArgumentError");  
});
Run Code Online (Sandbox Code Playgroud)


R. *_*nan 6

虽然其他答案肯定是有效的,但类似的 APITypeMatcher<Type>()现在已被弃用,并且您必须使用isA<TypeOfException>().

比如说之前的事情,

expect(() => range(5, 2), throwsA(TypeMatcher<IndexError>()));
Run Code Online (Sandbox Code Playgroud)

现在将是

expect(() => range(5, 2), throwsA(isA<IndexError>()));
Run Code Online (Sandbox Code Playgroud)


att*_*ona 5

使用throwsAwith检查异常TypeMatcher

注意isInstanceOf现在已弃用。

List range(start, stop) {
    if (start >= stop) {
      throw new ArgumentError("start must be less than stop");
    }
    // remainder of function
}


test("check argument error", () {
  expect(() => range(1, 2), throwsA(TypeMatcher<ArgumentError>()));
}); 
Run Code Online (Sandbox Code Playgroud)