TestCase 中的 NUnit 约束

问题描述 投票:0回答:1

我想测试一个可能返回 null 或不返回 null 的函数

Foo(string input)
。如果输入是
"A"
它应该返回 null。如果是
"B"
,则应返回非空。我在想以下问题:

[TestCase("A", Is.Null)]
[TestCase("B", Is.Not.Null)]
public void TestFoo(string input, Constraint expectedContraint) 
{
   var result = Foo(input);

   Assert.That(result, expectedConstraint);
}

这会失败,因为约束不是

constant expression, typeof expression or array creation expression of an attribute parameter type
。我可以简单地用
TestCaseSource
修复它,但我想知道是否有更好的方法来做到这一点。

一个选项:

[TestCase("A", true)]
[TestCase("B", false)]
public void TestFoo(string input, bool shouldBeNull) 
{
   var expectedConstraint = shouldBeNull ? Is.Null : Is.Not.Null;
   var result = Foo(input);

   Assert.That(result, expectedConstraint);
}

但在这种情况下,它会为测试添加逻辑,这是我想避免的。

而且,我感觉

Assert.That(result, expectedConstraint)
的可读性不是最好的。

解决这个问题的一个变体是

   if (shouldBeNull) {
      Assert.That(result, Is.Null);
   } else {
      Assert.That(result, Is.Not.Null);
   }

但是,这又为测试添加了一些逻辑。

避免逻辑并提高可读性的一种方法是将测试分为两个单独的测试。但在这种情况下,如果测试的设置非常复杂(这就是我想避免添加逻辑的原因),我会重复太多代码。

我认为在大多数情况下,这些解决方案中的任何一个都可以,并且没有太大区别,但我想知道是否有我错过的有趣的 NUnit 功能,或者有一些我可以应用的好的实践来编写测试更干净。谢谢!

c# nunit
1个回答
0
投票

我认为这有点固执己见,但这就是我们正在做的事情以及原因

(不过,我们正在使用 xUnit。但这并不重要,在这里。)

[TestCase("B")]
public void FooShouldReturnNotNull(string input) 
{
   SomeComplexSetup();
   var result = Foo(input);

   Assert.That(result, Is.Not.Null);
}

[TestCase("A")]
public void FooShouldReturnNull(string input) 
{
   SomeComplexSetup();
   var result = Foo(input);

   Assert.That(result, Is.Null);
}

private void SomeComplexSetup()
{
  // Just a stupid dummy for showcase
}

对于每个断言选项,我们都有一个单独的方法。因此,我们可以将测试数据源分成“类”,其中每个类都期望产生各自的结果。这使得哪个输入应该做什么变得非常清楚,而不需要测试代码内部的逻辑(这也可能有错误,我们不想测试测试,对吧?)。

可以通过分解共享代码并调用它来避免可能的 DRY 违规。 但我们不会因此而摔断腿。 一点点重复是可以接受的。如果您需要更改测试,无论如何您都需要谨慎行事。

注意如果您的测试用例同时运行,在将共享设置分解为线程安全/能够在所有情况下同时运行时,您显然需要注意。

© www.soinside.com 2019 - 2024. All rights reserved.