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

本文关键字:测试用例 属性 测试 异常 NUnit | 更新日期: 2023-09-27 18:32:26

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

假设我有一个方法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;
}

我想使用 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));
}

有没有办法指定一个测试用例,导致 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));
}

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

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

ExpectedException应该是

NUnit 2.X的正确方法,但它已从NUnit 3中删除。

在 NUnit Google 组和等效的 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>());
}

我同意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));
}

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