【发布时间】:2012-10-29 05:39:10
【问题描述】:
考虑一个根据传递的参数进行一些异常处理的函数:
List range(start, stop) {
if (start >= stop) {
throw new ArgumentError("start must be less than stop");
}
// remainder of function
}
如何测试是否引发了正确类型的异常?
【问题讨论】:
标签: dart
考虑一个根据传递的参数进行一些异常处理的函数:
List range(start, stop) {
if (start >= stop) {
throw new ArgumentError("start must be less than stop");
}
// remainder of function
}
如何测试是否引发了正确类型的异常?
【问题讨论】:
标签: dart
在这种情况下,有多种方法可以测试异常。简单地测试是否引发了非特定异常:
expect(() => range(5, 5), throwsException);
测试是否引发了正确类型的异常:
有几个用于一般用途的预定义匹配器,例如throwsArgumentError、throwsRangeError、throwsUnsupportedError 等。对于不存在预定义匹配器的类型,您可以使用TypeMatcher<T>。
expect(() => range(5, 2), throwsA(TypeMatcher<IndexError>()));
确保不引发异常:
expect(() => range(5, 10), returnsNormally);
测试异常类型和异常信息:
expect(() => range(5, 3),
throwsA(predicate((e) => e is ArgumentError && e.message == 'start must be less than stop')));
这是另一种方法:
expect(() => range(5, 3),
throwsA(allOf(isArgumentError, predicate((e) => e.message == 'start must be less than stop'))));
(感谢 Google 的 Graham Wheeler 提供最后 2 个解决方案)。
【讨论】:
expect(range(5, 3), throwsArgumentError),但在期望中没有捕获到异常。期望的第一个参数必须是一个匿名函数,在调用时最终会抛出。您的回答帮助我找到了那个愚蠢的错误,谢谢!
new isInstanceOf<ArgumentError>() 已被弃用。应该使用 TypeMatcher:例如throwsA(TypeMatcher<Exception>())
throwsA(isA<Exception>())
我喜欢这种方法:
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");
});
【讨论】:
作为@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.
),
),
);
【讨论】:
使用throwsA 和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>()));
});
【讨论】:
虽然其他答案肯定是有效的,但像 TypeMatcher<Type>() 这样的 API 现在已弃用,您必须使用 isA<TypeOfException>()。
例如,以前是什么,
expect(() => range(5, 2), throwsA(TypeMatcher<IndexError>()));
现在是
expect(() => range(5, 2), throwsA(isA<IndexError>()));
【讨论】:
对于简单的异常测试,我更喜欢使用静态方法API:
Expect.throws(
// test condition
(){
throw new Exception('code I expect to throw');
},
// exception object inspection
(err) => err is Exception
);
【讨论】:
我使用了以下方法:
首先你需要将你的方法作为一个 lambda 传递给期望函数:
expect(() => method(...), ...)
其次,您需要将throwsA 与isInstanceOf 结合使用。
throwsA 确保抛出异常,使用isInstanceOf 您可以检查是否抛出了正确的异常。
我的单元测试示例:
expect(() => parser.parse(raw), throwsA(isInstanceOf<FailedCRCCheck>()));
希望这会有所帮助。
【讨论】: