在NUnit 3中使用[TestCase]属性测试异常?

Cor*_*tus 29 .net c# nunit exception testcase

如何使用NUnit3测试TestCase中的异常?

假设我的方法Divide(a,b)定义如下:

public double Divide(double a, double b)
{
    if(Math.Abs(b) < double.Epsilon) throw new ArgumentException("Divider cannot be 0");
    return a/b;
}
Run Code Online (Sandbox Code Playgroud)

我想使用NUnit 3.0测试用例来测试这个方法,所以也许我有:

[TestCase(-10, 2, -5)]
[TestCase(-1, 2, -0.5)]
public void TestDivide(double a, double b, double result)
{
    Assert.That(_uut.Divide(a, b), Is.EqualTo(result));
}
Run Code Online (Sandbox Code Playgroud)

有没有办法指定一个测试用例,它会导致Divide()抛出ArgumentException,并以某种方式将其作为预期结果,例如:

[TestCase(-10, 2, -5)]
[TestCase(-1, 2, -0.5)]
[TestCase(-1, 0, ExpectedResult = TypeOf(ArgumentException)]
public void TestDivide(double a, double b, double result)
{
    Assert.That(_uut.Divide(a, b), Is.EqualTo(result));
}
Run Code Online (Sandbox Code Playgroud)

(当然我可以定义一个单独的测试方法并Assert.Throws()在此使用,所以这纯粹是出于好奇)

Chr*_*ris 32

ExpectedException 本来是NUnit 2.X的正确方法,但它已从NUnit 3中删除.

NUnit Google Group和等效的Dev组中有各种各样的讨论片段- 但看起来决定通常是一种更好的设计模式来测试预期结果和单独方法中的例外.(链接)

在NUnit 3中执行此操作的唯一方法是将其分解为两个单独的测试.(在NUnit核心团队回答的类似问题中确认,这里.)

[TestCase(-10, 2, -5)]
[TestCase(-1, 2, -0.5)]
public void TestDivide(double a, double b, double result)
{
    Assert.That(_uut.Divide(a, b), Is.EqualTo(result));
}

[TestCase(-1, 0)]
public void TestDivideThrows(double a, double b)
{
    Assert.That(() => _uut.Divide(a, b), Throws.TypeOf<ArgumentException>());
}
Run Code Online (Sandbox Code Playgroud)

  • "通常是一个更好的设计模式来测试预期结果,以及单独方法中的异常" - 我无法在不重构1000多个测试的情况下更新我的代码上的nunit框架,因为"通常更好的设计模式".这不是证明破坏变化的好方法 (4认同)

Oli*_*ter 9

我同意 Corpus Gigantus 的答案,但你为什么不简化这样的事情:

[TestCase(-10, 2, -5)]
[TestCase(-1, 2, -0.5)]
[TestCase(-1, 0, null, typeof(ArgumentException))]
public void TestDivide(double a, double b, double result, Type exception = null)
{
    if(exception != null)
    {
        Assert.Throws(exception, delegate { _uut.Divide(a, b);  });
                
    } else Assert.That(_uut.Divide(a, b), Is.EqualTo(result));
}
Run Code Online (Sandbox Code Playgroud)

这样,预期的异常也是测试参数的一部分,请注意,只能有两种结果,除法成功或抛出。