【问题标题】:Test that a specific exception didn't happen in NUnit测试 NUnit 中没有发生特定异常
【发布时间】:2019-11-11 08:23:16
【问题描述】:

首先,这与this question 非常相似。

我要做的是运行一个测试,如果程序没有抛出特定异常,但如果程序确实该特定异常,则该测试通过,我希望 NUnit 在测试运行程序中添加一条消息,解释此特定异常的可能原因。

情况是这样,我正在做the bowling score kata,我想,如果有人为第 22 卷输入一个值会发生什么(假设最后一帧有备用,每卷的最高数量应该是 21)。

我的解决方案使用 21 个整数的数组,并且我创建了一个输入 22 个整数的测试。

当我查看this page 时,我看到了此语法的选项:

Assert.DoesNotThrow( TestDelegate code, string message );

我认为这行代码应该是这样的,但我知道(并且编译器在抱怨)使用 typeof 不会让我得到测试委托代码。

[Test]
public void ShouldIgnore22ndRoll()
{
     Assert.DoesNotThrow(typeof(System.IndexOutOfRangeException), "There should never be more than 21 rolls in a game");
     RollAllTheSameNumber(1, 22);
}

底线,如果我看到这个异常,我知道问题是什么,并且我想告诉我未来的我这个问题是什么(通过填充发送给测试运行程序的消息)。

任何其他例外,我将不得不弄清楚,但这个例外是我已经考虑过的。

我该如何写这个断言?

编辑:

这是变量定义:

int rollNumberDuringDataInput = 0;
const int AllowableNumberOfRolls = 21;

这是固定代码(默默地忽略任何超过 21 号的滚动):

public void AddPins(int pins)
{
    if (rollNumberDuringDataInput < AllowableNumberOfRolls)
    {
        rolls[rollNumberDuringDataInput++] = pins;
    }
}

下面是允许超过 21 次滚动而导致测试失败的代码:

public void AddPins(int pins)
{
    rolls[rollNumberDuringDataInput++] = pins;
}

目前,这是在测试运行器中生成的消息: 消息:System.IndexOutOfRangeException:索引超出了数组的范围。

我希望这个异常的消息是什么(并且只有这个异常 消息:System.IndexOutOfRangeException:游戏中的掷骰数不得超过 21 次。

如果有人删除了守卫逻辑,我希望测试运行器中的消息告诉我为什么该守卫存在背后的业务逻辑。

如果您从未处理过一系列错误(其中一个修复暴露了代码中的旧漏洞,而该修复暴露了另一个漏洞,并且该修复再次暴露了第一个错误;重复) 算自己幸运。

我看到,我认为,这是一种捕获特定不良条件的方法,如果它再次出现,我们可以迅速通知破坏方,为什么他们的修复破坏了代码。

【问题讨论】:

  • 您实际上是在 one 测试中测试 两个 不同的场景,这是一个糟糕的测试设计,因为当它失败时,原子语句不足以描述 是什么情况。想象一下测试一个装有 5 个苹果的碗。你做了一个测试,说明你应该能够从碗里取出 5 个苹果,然后再取出 6 个,但忽略了没有更多苹果的事实。有点奇怪。你应该把你的测试分成Test2ndRollPass()Test22ndRollFail(),后者包含Assert.Throws&lt;IndexOutOfRangeException&gt;(...)语句。
  • ...此外,如果在 {1..21} 期间由于某些未知原因在代码的内部滚动中抛出了无法预料的IndexOutOfRangeException,现在它将被忽略,因为您的测试是假设错误来自22nd roll,即incorrect
  • (在上面添加了附加信息)异常不是通过条件,它仍然应该失败,我只想将测试运行器中的消息从异常更改为异常,加上原因.在这种情况下,稍后必须有人专门回来,并更改代码……只要对所有输入进行清理,使 21 次滚动永远不会发生,就不会有问题,但几年后,当我们得到一个新的不清理他们的输入的供应商我们有一个我们必须调试的问题。我想留言说,“你脱掉了我们想要留在代码中的护栏”

标签: c# nunit tdd


【解决方案1】:

根据你的描述

如果我明白你在问什么,那么你应该改写你对未来自己说的话。

[Test]
public void ShouldIgnore22ndRoll() {    

     Assert.Throws<System.IndexOutOfRangeException>(() => RollAllTheSameNumber(1, 22), "More than 21 rolls in a game should fail.");

}

除预期之外的任何其他异常都意味着代码未按预期运行。

【讨论】:

  • 您好 Nkosi,不,这是我添加的测试,然后我添加了代码来覆盖,因此代码不会引发异常,除非有人更改代码以移除护栏。我不想要异常,但如果它发生了,那么我已经知道问题出在哪里,我想告诉破坏代码的开发人员,为什么他们的更改破坏了代码。
猜你喜欢
  • 2013-10-08
  • 2014-08-14
  • 2013-03-16
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
  • 2011-07-31
  • 2018-07-22
  • 1970-01-01
相关资源
最近更新 更多