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

时间:2008-12-22 11:11:16

标签: unit-testing exception nunit

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

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

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

try catch事情看起来像这样:

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

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

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

2 个答案:

答案 0 :(得分:7)

嗯,您可以通过提取实用程序方法将其减少到一个死区,例如

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

用以下方式调用:

ExpectException<ArgumentNullException>
    (() => controller.Foo(null, new SecondParameter());

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

答案 1 :(得分:6)

来自release notes of 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);
}

http://www.andreas-schlapsi.com/2008/03/31/nunit-247-includes-rowtest-extension/ 代码来自Google code

的Nunit RowTestExtension的源代码