我如何使用Assert(或其他测试类)来验证在使用MSTest/Microsoft.VisualStudio.TestTools.UnitTesting时抛出了异常?
当前回答
这是测试方法的一个属性…你不使用Assert。看起来是这样的:
[ExpectedException(typeof(ExceptionType))]
public void YourMethod_should_throw_exception()
其他回答
通常你的测试框架会给出答案。但如果它不够灵活,你可以这样做:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (GoodException) { }
正如@Jonas指出的,这并不适用于捕捉基本异常:
try {
somethingThatShouldThrowAnException();
Assert.Fail(); // raises AssertionException
} catch (Exception) {
// Catches the assertion exception, and the test passes
}
如果绝对必须捕获Exception,则需要重新抛出Assert.Fail()。但实际上,这是一个你不应该手写的信号;检查测试框架中的选项,或者查看是否可以抛出更有意义的异常进行测试。
catch (AssertionException) { throw; }
您应该能够根据自己的需要调整这种方法——包括指定要捕获的异常类型。如果你只期望某些类型,完成catch块:
} catch (GoodException) {
} catch (Exception) {
// not the right kind of exception
Assert.Fail();
}
对于“Visual Studio Team Test”,似乎您将ExpectedException属性应用到测试的方法。
文档中的示例:使用Visual Studio团队测试的单元测试演练
[TestMethod]
[ExpectedException(typeof(ArgumentException),
"A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}
有一个很棒的库叫做NFluent,它可以加速和简化你编写断言的方式。
编写抛出异常的断言非常简单:
[Test]
public void given_when_then()
{
Check.ThatCode(() => MethodToTest())
.Throws<Exception>()
.WithMessage("Process has been failed");
}
在我正在做的一个项目中,我们有另一个解决方案。
首先,我不喜欢ExpectedExceptionAttribute,因为它确实考虑了导致异常的方法调用。
我用一个helper方法来代替它。
Test
[TestMethod]
public void AccountRepository_ThrowsExceptionIfFileisCorrupt()
{
var file = File.Create("Accounts.bin");
file.WriteByte(1);
file.Close();
IAccountRepository repo = new FileAccountRepository();
TestHelpers.AssertThrows<SerializationException>(()=>repo.GetAll());
}
HelperMethod
public static TException AssertThrows<TException>(Action action) where TException : Exception
{
try
{
action();
}
catch (TException ex)
{
return ex;
}
Assert.Fail("Expected exception was not thrown");
return null;
}
很整洁,不是吗?)
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>();