协慌网

登录 贡献 社区

如何使用 Assert 验证是否抛出了异常?

如何使用 Assert(或其他 Test 类?)来验证是否抛出了异常?

答案

对于 “Visual Studio Team Test”,您似乎将 ExpectedException 属性应用于测试的方法。

此处文档中的示例: 使用 Visual Studio Team Test 进行的单元测试演练

[TestMethod]
[ExpectedException(typeof(ArgumentException),
    "A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
   LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}

通常,您的测试框架将为此提供答案。但如果它不够灵活,你可以随时这样做:

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();
}

我实现这个的首选方法是编写一个名为 Throws 的方法,并像使用任何其他 Assert 方法一样使用它。遗憾的是,.NET 不允许您编写静态扩展方法,因此您不能使用此方法,就好像它实际上属于 Assert 类中的构建一样; 只需制作一个名为 MyAssert 或类似的东西。这个类看起来像这样:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace YourProject.Tests
{
    public static class MyAssert
    {
        public static void Throws<T>( Action func ) where T : Exception
        {
            var exceptionThrown = false;
            try
            {
                func.Invoke();
            }
            catch ( T )
            {
                exceptionThrown = true;
            }

            if ( !exceptionThrown )
            {
                throw new AssertFailedException(
                    String.Format("An exception of type {0} was expected, but not thrown", typeof(T))
                    );
            }
        }
    }
}

这意味着您的单元测试如下所示:

[TestMethod()]
public void ExceptionTest()
{
    String testStr = null;
    MyAssert.Throws<NullReferenceException>(() => testStr.ToUpper());
}

其外观和行为更像是其他单元测试语法。