在没有ExpectedException属性的情况下,期望nUnit中的异常

Tig*_*ine 3 nunit unit-testing exception

我有多个参数的方法,通过在任何参数为null时抛出ArgumentNullExceptions和ArgumentExceptions来防止输入错误.

所以有两种明显的方法来测试它:

  • 使用[ExpectedException]属性对每个参数进行一次测试
  • 使用多个try {} catch块对所有参数进行一次测试

try catch事情看起来像这样:

try 
{
    controller.Foo(null, new SecondParameter());
    Assert.Fail("ArgumentNullException wasn't thrown");
} catch (ArgumentNullException)
{}
Run Code Online (Sandbox Code Playgroud)

有一个小问题.如果测试通过,Assert.Fail永远不会被调用,因此将突出显示为未涵盖的测试代码(通过NCover).

我知道这实际上不是一个问题,因为它是我想要100%覆盖的业务代码,而不是测试代码.如果有一种方法可以将多个异常抛出调用压缩到一个测试用例而不需要死亡的LoC,我仍然很好奇吗?

Jon*_*eet 7

那么,你可以通过提取一个实用工具方法将它减少到一个死线,例如

public void ExpectException<T>(Action action) where T : Exception
{
    try
    {
        action();
        Assert.Fail("Expected exception");
    }
    catch (T)
    {
        // Expected
    }
}
Run Code Online (Sandbox Code Playgroud)

称之为:

ExpectException<ArgumentNullException>
    (() => controller.Foo(null, new SecondParameter());
Run Code Online (Sandbox Code Playgroud)

(你不需要将它包装在IDE中,当然...... SO的行长度非常短.)


Pet*_*pac 6

NUnit 2.4.7的发行说明中,NUnit 现在包括由Andreas Schlapsi编写的RowTest扩展,它的扩展程序集.此扩展允许您编写带参数的测试方法,并使用RowAttribute提供多组参数值.要使用RowTest,您的测试必须引用nunit.framework.extensions程序集.

它向NUnit添加了MbUnit的RowTest功能.

你可以写下这样的东西:

[RowTest]
[Row(1, 2, 3)]
[Row(3, 4, 8, TestName="Special case")]
[Row(10, 10, 0, TestName="ExceptionTest1"
    , ExpectedException=typeof(ArgumentException)
    , ExceptionMessage="x and y may not be equal.")]
[Row(1, 1, 0, TestName="ExceptionTest2"
    , ExpectedException=typeof(ArgumentException)
    , ExceptionMessage="x and y may not be equal.")]
public void AddTest(int x, int y, int expectedSum)
{
  int sum = Sum(x, y);
  Assert.AreEqual(expectedSum, sum);
}
Run Code Online (Sandbox Code Playgroud)

http://www.andreas-schlapsi.com/2008/03/31/nunit-247-includes-rowtest-extension/ 代码来自Google代码中 Nunit RowTestExtension的源代码