我如何允许使用 [ExpectedException(typeof(ArgumentException))] 在单元测试中断言?

How could I allow Assert in Unit Test with [ExpectedException(typeof(ArgumentException))]?

我发现,那个简单的单元测试

    [TestMethod()]
    [ExpectedException(typeof(ArgumentException))]
    public void UT_UU()
    {
    }

有误

Message: Test method did not throw expected exception System.ArgumentException.

我成功地使用 [ExpetedException] 来测试错误消息输出,但是,在单元测试中使用 Assert of side variables 进行的任何检查都会导致错误。

我可以通过某种方式装饰我的测试来避免它吗?或者是 "political error"?

with [ExpectedException(typeof(ArgumentException))] 仅当被测方法生成您指定的类似类型的异常时,您的单元测试才会通过。在你的情况下 ArgumentException 否则它将失败并显示你发布的消息。

因此,从本质上讲,您将不得不通过注入该异常来使您的测试方法失败。目前您的测试方法没有抛出预期的异常(它实际上没有执行任何操作)

例如下面的测试方法会通过

[TestMethod()]
[ExpectedException(typeof(ArgumentException))]
public void UT_UU()
{
   throw new ArgumentException();
}

如果您的测试被隔离到足以只测试一件事,那么在用 ExpectedException 修饰的测试主体中使用 Assert 语句并不真正适合该模式。如果您遵循 "Arrange, Act, Assert" 模式,那么在这种情况下 Assert 由 ExpectedExceptionAttribute 本身处理,测试主体中的最后一行代码将是 "Act" 因为它应该导致异常发生。如果您需要了解有关抛出异常的更具体信息以确保系统满足行为预期,那么我会在测试本身中使用 try/catch 以便能够提供更细粒度的检查:

[TestMethod]
public void UT_UU()
{
    // Arrange
    var subject = new Foo();
    try
    {
        // Act
        subject.Bar();
    }
    catch(ArgumentException ae)
    {
        Assert.AreEqual("my message", ae.Message);
        return;
    }
    catch(Exception e)
    {
        Assert.Fail("Thrown exception was of wrong type"); // would provide more detail here
    }
    Assert.Fail("exception should have been thrown");
}

显然只使用 ExpectedException 很好,因为它可以让您进行非常干净的测试而没有额外的噪音。或者,如果您打算重新使用这种类型的测试,您可以编写 ExpectedException 的派生版本,它允许您指定要检查的其他特征(如 Message),而不仅仅是类型。