使用xUnit编写单元测试的异常信息

78

我目前正在将我的 MsTest 单元测试转换为 xUnit。在 xUnit 中,有没有一种方法可以测试异常消息?测试异常消息是否正确,而不是仅测试异常类型?

8个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
139

我认为测试异常类型和消息是正确的做法。在xUnit中,这两者都很容易实现:

var exception = Assert.Throws<AuthenticationException>(() => DoSomething());
Assert.Equal(message, exception.Message);

3
不需要这样做,你需要使用Assert.ThrowsAsync<>来实现。 - jfmg
我确定我漏掉了显而易见的东西,但第一行中的message参数是什么? - Mark Embling
@MarkEmbling 感谢您指出这个问题 - 这可能是一个打字错误。我已经更新了答案。 - the_joric

9
最好使用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);
    }
希望这能帮到你...

2
xUnit2007:不要使用 typeof(System.DivideByZeroException) 表达式来检查类型。相反,您可以使用:Assert.IsType<DivideByZeroException>(exception)。 - ggeorge

2

类似这样的

 var ex = Record.Exception(() => DoSomeThing());
 Assert.IsType(typeof(ArgumentNullException), ex);
 Assert.True(ex.Message.Contains("Your exception message"));

1

顺便说一句,Resharper不喜欢使用typeof,而是建议使用Assert.IsType,例如:

var ex = Record.Exception(() => new FooController(null, null));
Assert.IsType<ArgumentNullException>(ex);

1
xUnit使用Assert.Throws来测试异常类型。如果需要,您可以捕获异常并针对消息进行断言。我认为通常情况下,您希望测试是否抛出了预期的异常,而确切的消息并不是必要的。
Assert.Throws<ArgumentNullException>()

除非您正在单元测试自定义异常并且希望确保生成的消息符合您的预期,否则可能会有例外情况。或者,如果可以使用相同的异常类型但具有不同消息的两种方式抛出,则针对消息进行断言将是有价值的。


1
Throws() 返回异常 -- 不需要捕获它。 - the_joric

0

异常并不比测试的任何其他预期结果更加特殊。测试消息是否正确是很自然的事情,因为同一种异常类型可以有两个不同的消息。然而,我个人认为这并非必须,至少在所有异常中都不是。

在我们的项目中,每个应用程序异常也附带一个“Message”对象,因此我们仅验证MessageId,而不验证消息参数是否正确或消息文本是否正确。例如,如果消息文本为“提供了错误的参数<{0}>”,我们不会检查传递给格式化程序{0}的参数是否符合预期 - 这不是意图。消息具有唯一的ID-因此,我们验证异常上的MessageID是否为'WRONG_PARAMETER_PROVIDED'。


0

考虑到异步编程的问题,新版本将会是:

var ex = await Record.ExceptionAsync(() => myMethod(myParams));
Assert.IsType<SomeException>(ex);
Assert.Equal("My text of the error.", ex.Message);

-1
xUnit网站还提到了"Record.Exception"结构。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,