3

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

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

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

try catch 看起来像这样:

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

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

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

4

2 回答 2

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 上的行长很短。)

于 2008-12-22T11:30:12.923 回答
6

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

它将 MbUnit 的 RowTest 功能添加到 NUnit。

您可以编写如下内容:

[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 代码 中 Nunit RowTestExtension 的源代码

于 2008-12-23T08:11:10.187 回答