如何解决如何为复杂对象的默认创建自定义 AutoFixture?
我有一个相当大的类,使用实体框架和一些列表属性作为一对多关系。我使用 AutoFixture 创建测试数据并摆脱循环引用,我设置了很多“无”。但是要一遍又一遍地复制相同的代码。我不知道如何自定义初始创建。看起来像这样
作品:
var entity = fixture.Build<MyObject>()
.Without(c => c.Cars)
.Without(c => c.Boats)
.Without(c => c.Motorcycles)
.Without(c => c.Skateboards)
.Create();
我希望每次使用夹具创建 MyObject 时将这些设置为默认值(然后在某些情况下可以覆盖它们)
我尝试创建一个这样的类
public class Conventions: ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<MyObject>
(c => c
.Without(c => c.Cars)
.Without(c => c.Boats)
.Without(c => c.Motorcycles)
.Without(c => c.Skateboards)
);
然后使用它:
var fixture = new Fixture();
fixture.Customize(new Conventions());
var entity = fixture.Build<MyObjec>().Create();
但不,它在递归声明上失败
解决方法
您描述的行为是有意为之。 .Build<T>()
自定义会创建一次性使用的自定义,该自定义会忽略之前分配的所有自定义。
如果只是想使用以前应用的类型自定义来创建实例,那么您需要做的就是从测试中删除 .Build<T>()
语句并直接使用 .Create()
。这将避免从头开始创建自定义。
var fixture = new Fixture();
fixture.Customize(new Conventions());
var entity = fixture.Create<MyObject>();
由于您使用的是 EntityFramework,因此您的导航属性很可能被标记为 virtual
。您可以编写一个 IRequestSpecification
来标识虚拟成员并使用 Omitter
省略所有导航属性。
解决您的问题的另一种方法是考虑更改域模型的设计。例如,问问自己允许域模型的客户端“设置/替换”船的集合是否是有效的操作。如果答案为“否”,您可能想要更改模型,以便此规则反映在设计本身中,即将设置器设为私有并将集合更改为只读集合。如果您这样做,AutoFixture 将忽略导航属性,您将能够使用适当的业务规则设置它们的值。
最后,如果您仍想重用自定义的一部分,您可以以允许这种操作的方式扩展 AutoFixture。 Customize<T>()
和 Build<T>()
都使用 IPostprocessComposer<T>
接口来组成内联自定义。您可以编写一个扩展方法来干预该过程并将自定义委托给第三方。
public static class ComposerExtensions
{
public static IPostprocessComposer<T> Using<T>(this IPostprocessComposer<T> source,IPartialPostprocessComposer<T> composer)
{
return composer.Compose(source);
}
}
现在假设第三方看起来像这样。
public class MyClassPartialComposer : IPartialPostprocessComposer<MyClass>
{
public IPostprocessComposer<MyClass> Compose(IPostprocessComposer<MyClass> source)
{
return source
.Without(x => x.Cars)
.Without(x => x.Boats);
}
}
您的自定义可能如下所示。
var actual = fixture.Build<MyClass>()
.Using(new MyClassPartialComposer())
.With(x => x.Name,"hello")
.Create();
通过这种方法,您还可以组成部分内联自定义。
请记住,虽然 AutoFixture 不正式支持最后一种方法,但您必须自己定义扩展方法和部分 Composer 实现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。