我如何使用Assert(或其他测试类)来验证在使用MSTest/Microsoft.VisualStudio.TestTools.UnitTesting时抛出了异常?


当前回答

在VS内置单元测试中,如果你只是想验证抛出了“任何异常”,但你不知道类型,你可以使用catch all:

[TestMethod]
[ExpectedException(typeof(Exception), AllowDerivedTypes = true)]
public void ThrowExceptionTest()
{
    //...
}

其他回答

我知道这个帖子很老了,有很多很好的答案,但值得一提的是,局部函数可以以一种非常简单的方式提供帮助。

//Arrange

//Act
void LocalFunction() => mr.ActualMethod(params);

//Assert
Assert.Throws<Exception>(LocalFunction);

FluentAssertions例子

为那些使用该库的用户添加一个使用FluentAssertions的示例。

// act
Action result = () => {
    sut.DoSomething();
};

// assert
result.Should().Throw<Exception>();

异步的例子

// act
Func<Task> result = async () => {
    await sut.DoSomethingAsync();
};

// assert
await result.Should().ThrowAsync<Exception>();

如果你使用NUNIT,你可以这样做:

Assert.Throws<ExpectedException>(() => methodToTest());

也可以存储抛出的异常以便进一步验证:

ExpectedException ex = Assert.Throws<ExpectedException>(() => methodToTest());
Assert.AreEqual( "Expected message text.", ex.Message );
Assert.AreEqual( 5, ex.SomeNumber);

参见:http://nunit.org/docs/2.5/exceptionAsserts.html

您可以通过简单的一行代码来实现这一点。

如果你的foo.bar()操作是异步的:

await Assert.ThrowsExceptionAsync<Exception>(() => foo.bar());

如果foo.bar()不是异步的

Assert.ThrowsException<Exception>(() => foo.bar());

这适用于Visual Studio Team Test(又名MSTest) 在处理数据库或http事务时。系统应该在某处抛出异常,使用Assert.ThrowExceptionAsync<>()将捕获您的throw事件。(在这些情况下,Assert.ThrowException<>()不会捕获异常)。

   [TestMethod]
   public void Invalid_Input_UserName_Should_Throw_Exception()
   {
       await Assert.ThrowExceptionAsync<ExpectedExceptionType>(()=> new LogonInfo(InvalidInputInUserNameFormat,"P@ssword"));
   }