正如您所说,您在测试中遇到的摩擦很可能是域模型中设计问题的标志。理想情况下,您应该听取您的测试并从根本上解决问题。但是,鉴于在这种情况下不可行,这里有一个解决方法。
您可以使用该方法将其配置为始终按固定顺序Fixture
返回对象。LineItem
Register<T>(Func<T> creator)
这是一个打包在自定义项中的示例:
public class GenerateLineItemFromFixedSequence : ICustomization
{
public void Customize(IFixture fixture)
{
var items = CreateFixedLineItemSequence(fixture);
fixture.Register(() => GetRandomElementInSequence(items));
}
private static IEnumerable<LineItem> CreateFixedLineItemSequence(IFixture fixture)
{
return fixture.CreateAnonymous<LineItem[]>();
}
private static LineItem GetRandomElementInSequence(IEnumerable<LineItem> items)
{
var randomIndex = new Random().Next(0, items.Count());
return items.ElementAt(randomIndex);
}
}
为了在测试的上下文中应用此行为,只需将自定义添加到Fixture
对象:
fixture.Customize(new GenerateLineItemFromFixedSequence());
同样,您可以创建其他自定义项,以生成LineItem
处于不同状态的对象的固定序列,例如您提到的部分发货的订单,并在不同的测试中使用它们。
观察
有趣的是,这种定制可以是通用的,因为算法本身并没有与正在创建的对象的类型相耦合。这将有效地将其转化为一种战略。
因此,通过引入通用参数来修改自定义:
public class GenerateFromFixedSequence<T> : ICustomization
{
public void Customize(IFixture fixture)
{
var items = CreateFixedSequence(fixture);
fixture.Register(() => GetRandomElementInSequence(items));
}
private static IEnumerable<T> CreateFixedSequence(IFixture fixture)
{
return fixture.CreateAnonymous<T[]>();
}
private static T GetRandomElementInSequence(IEnumerable<T> items)
{
var randomIndex = new Random().Next(0, items.Count());
return items.ElementAt(randomIndex);
}
}
将允许您将其用于不同的对象:
fixture.Customize(new GenerateFromFixedSequence<LineItem>());
fixture.Customize(new GenerateFromFixedSequence<Order>());
fixture.Customize(new GenerateFromFixedSequence<Shipment>());