将DRY应用于自动混合“构建”语句
假设我有这个具体的类:
public partial class User { public int ID { get; set; } public string Email { get; set; } public string FullName { get; set; } }
我想创建一个具有有效电子邮件地址的匿名实例,并且fullname字段不超过20个字符。 我可以做这个:
var fixture = new Fixture(); var anonUser = fixture.Build() .With(x => x.Email, string.Format("{0}@fobar.com", fixture.Create())) .With(x => x.FullName, fixture.Create()Substring(0,20)) .Create();
有没有办法可以在一个地方定义它,以便AF知道我可以通过使用以下方式获得我的自定义anon类:
var newAnon = fixture.Build();
你有各种选择。 在我看来,最好的选择是应用GOOS原则来听你的测试 。 当测试变得难以编写时,是时候重新考虑被测系统(SUT)的设计了。 AutoFixture倾向于放大这种效果。
重构为值对象
如果您要求Email
和FullName
属性应具有特别受约束的值,则可能表示目标API将受益于定义显式Email
和FullName
值对象 ,而不是Primitive Obsession 。 规范的AutoFixture示例是关于电话号码 。
使用数据注释
您还可以使用数据注释来提供有关值的约束的AutoFixture提示。 并非所有数据注释属性都受支持,但您可以同时使用MaxLength和RegularExpression 。
它可能看起来像这样:
public partial class User { public int ID { get; set; } [RegularExpression("regex for emails is much harder than you think")] public string Email { get; set; } [MaxLenght(20)] public string FullName { get; set; } }
就个人而言,我不喜欢这种方法,因为我更喜欢适当的封装 。
使用自定义
而不是使用Build
方法,使用Customize
方法:
var fixture = new Fixture(); fixture.Customize(c => c .With(x => x.Email, string.Format("{0}@fobar.com", fixture.Create()) .With(x => x.FullName, fixture.Create ().Substring(0,20))); var newAnon = fixture.Create();
编写一个约定驱动的Specimen Builder
最后,您可以编写一个约定驱动的自定义 :
public class EmailSpecimenBuilder : ISpecimenBuilder { public object Create(object request, ISpecimenContext context) { var pi = request as PropertyInfo; if (pi == null) { return new NoSpecimen(request); } if (pi.PropertyType != typeof(string) || pi.Name != "Email") { return new NoSpecimen(request); } return string.Format("{0}@fobar.com", context.Resolve(typeof(string))); } }
我非常喜欢这种方法,因为我可以在这里放置任意复杂的逻辑,因此我不需要创建大量的一次性自定义,而是可以使用一小组约定来驱动整个测试套件。 这也倾向于使目标代码更加一致。
- AutoFixture:配置Open Generics Specimen Builder
- AutoFixture – 如何调用方法,如何设置autoproperty的私有setter?
- 如何指示AutoFixture不打扰填写某些属性?
- AutoFixture作为Automocking容器与Automocking差异?
- AutoFixture:PropertyData和异构参数
- 如何让AutoFixture AutoMoq从实例化对象中的注入服务返回结果?
- 我应该使用AutoFixture来测试我的洋葱的核心元素,它没有依赖性吗?
- 如何创建始终在AutoFixture中设置预定义值的类列表?
- AutoFoture与AutoMoq和具体对象注入