我目前正在将我的 MsTest 单元测试转换为 xUnit。使用 xUnit,有没有办法测试异常消息?测试异常消息而不是仅测试异常类型是否正确?
8 回答
我认为测试异常类型和消息是正确的。两者在 xUnit 中都很容易:
var exception = Assert.Throws<AuthenticationException>(() => DoSomething());
Assert.Equal(message, exception.Message);
最好使用 Record.Exception 方法,因为它匹配 AAA 模式:
[Fact]
public void Divide_TwoNumbers_ExpectException()
{
var sut = new Calculator();
var exception = Record.Exception(() => sut.Divide(10, 0));
Assert.IsType(typeof(DivideByZeroException), exception);
}
希望这可以帮助 ...
像这样的东西
var ex = Record.Exception(() => DoSomeThing());
Assert.IsType(typeof(ArgumentNullException), ex);
Assert.True(ex.Message.Contains("Your exception message"));
xUnit 使用 Assert.Throws 来测试异常类型。如果需要,您可以捕获异常并针对消息断言。我认为通常您想测试是否引发了预期的异常,并且确实不需要确切的消息。
Assert.Throws<ArgumentNullException>()
如果您有一个正在单元测试的自定义异常并且您想确保生成的消息是您所期望的,则可能会出现异常。或者,如果有两种方法可以抛出相同的异常类型但具有不同的消息,那么针对消息进行断言将是有价值的
顺便说一句,Resharper 不喜欢使用 typeof 并建议 Assert.IsType 代替,例如
var ex = Record.Exception(() => new FooController(null, null));
Assert.IsType<ArgumentNullException>(ex);
异常与测试的任何其他预期结果没有什么不同。测试消息是否正确是很自然的,因为两条不同的消息可能来自相同的异常类型。但是 - 我个人不认为这是强制性的,至少不是在所有例外情况下。
在我们的项目中,每个应用程序异常还附加了一个“消息”对象,因此我们只验证MessageId,我们不验证消息参数是否正确或消息的文本。例如,如果消息文本是“提供了错误的参数 <{0}>”,我们不会检查传递给格式 {0} 的参数是否符合预期 - 这不是意图。该消息具有唯一的 id - 因此我们验证异常上的MessageID是否为“WRONG_PARAMETER_PROVIDED”。
鉴于异步的东西,新版本将是
var ex = await Record.ExceptionAsync(() => myMethod(myParams));
Assert.IsType<SomeException>(ex);
Assert.Equal("My text of the error.", ex.Message);
xUnit 网站还提到了“Record.Exception”构造。