【发布时间】:2014-01-17 21:06:19
【问题描述】:
我在 xUnit 单元测试中使用AutoData。我偶尔需要为我的测试提供特定数量的对象。考虑以下类:
public class Recipient
{
public void Receive(
CallingBird bird1,
CallingBird bird2,
CallingBird bird3,
CallingBird bird4
)
{
this.Bird1 = bird1;
this.Bird2 = bird2;
this.Bird3 = bird3;
this.Bird4 = bird4;
}
public CallingBird Bird1 { get; private set; }
public CallingBird Bird2 { get; private set; }
public CallingBird Bird3 { get; private set; }
public CallingBird Bird4 { get; private set; }
}
如果没有 AutoData,我可能会编写这样的测试:
[Fact]
public void All_Birds_Are_Populated()
{
var bird1 = new CallingBird();
var bird2 = new CallingBird();
var bird3 = new CallingBird();
var bird4 = new CallingBird();
var sut = new Recipient();
sut.Receive(bird1, bird2, bird3, bird4);
Assert.NotNull(sut.Bird1);
Assert.NotNull(sut.Bird2);
Assert.NotNull(sut.Bird3);
Assert.NotNull(sut.Bird4);
}
在这样的情况下使用 AutoData,我一直在请求我需要的对象数组的数组,以便获得足够的不同实例(假设我需要不同的实例),如下所示:
[Theory, Autodata]
public void All_Birds_Are_Populated(CallingBird[][] birds, Recipient sut)
{
sut.Receive(birds[0][0], birds[0][1], birds[0][2] ,birds[1][0]);
Assert.NotNull(sut.Bird1);
Assert.NotNull(sut.Bird2);
Assert.NotNull(sut.Bird3);
Assert.NotNull(sut.Bird4);
}
}
当您从 AutoData 请求数组时,它会为您提供包含 3 个对象的数组。所以,如果我需要 4 个,我可以要求 2 个数组,或者一个数组数组(如图所示),在这个例子中这比要求两个数组更浪费。它有效,但我经常要求提供比我需要的更多的实例。想象一种情况,其中计数更高,创建对象的成本更高,等等。
您能否建议一种更简洁的方法来请求类型的 N 个对象作为单元测试参数,其中 N 正是我需要的数字?
【问题讨论】:
-
您有一个带有 非常具体 个参数的 SUT 方法,但您希望您的测试方法为您提供 一般数量 个实例.这说明了 SUT 的 API 什么?
-
好吧,我实际上希望我的测试方法也为我提供非常具体数量的参数。通常,我可能会回答您的问题,说我的 SUT 的 API 应该更改为具有类型为
CallingBird[]的单个属性,但这是在建模父对象恰好具有相同类型的 4 个子属性的东西,每个子属性具有不同的值.我不知道如何设计它并满足正好有 4 个 CallingBirds。 -
因此,您拥有需要填充的
Receive方法。它有一个非常特殊的签名。现在您想使用[AutoData]为您提供它的值。这意味着您也必须为测试方法提出适当的签名。您如何对这样的方法签名进行建模以适应您想要做的事情? -
啊。只需请求 4 个
CallingBird实例,每个实例作为它们自己的测试方法参数,加上RecipientSUT。这是你在暗示的吗?完全有道理。我想我在上面的示例中稍微提炼了一些情况,但我想象需要更多数量的实例(10+),以及在测试方法中可能会变得多么笨拙。但是,我想这说明了 SUT 的方法签名中的一个潜在问题,如果没有,那么我应该能够在我的测试方法中容忍与我在我的 SUT 方法中相同的签名长度,对吧?跨度> -
这正是我的意思 :) 很抱歉含糊其辞,但如果我能让您自己找到解决方案,我真的很高兴 :) 现在寻找替代方案(即将推出)!
标签: c# arrays unit-testing autofixture