假设我有这个具体的课程:
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<User>()
.With(x => x.Email, string.Format("{0}@fobar.com", fixture.Create<string>()))
.With(x => x.FullName, fixture.Create<string>()Substring(0,20))
.Create();
有没有办法可以在一个地方定义这个,所以AF知道我可以通过使用以下方式获得我自定义的anon类:
var newAnon = fixture.Build<User>();
答案 0 :(得分:12)
你有各种选择。在我看来,最好的选择是应用听取您的测试的GOOS原则。当测试变得难以编写时,是时候重新考虑被测系统(SUT)的设计了。 AutoFixture倾向于放大这种效果。
重构为价值对象
如果您要求Email
和FullName
属性具有特别受约束的值,则可能表明目标API将受益于定义显式Primitive Obsession而不是canonical AutoFixture example is about phone numbers。 1}}和Email
值对象。 data annotations。
使用数据注释
您还可以使用MaxLength提供有关值约束的AutoFixture提示。并非所有数据注释属性都受支持,但您可以同时使用RegularExpression和proper encapsulation。
它可能看起来像这样:
FullName
就个人而言,我不喜欢这种方法,因为我更喜欢convention-driven customization。
使用自定义
不使用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<T>
方法:
Customize<T>
编写会议驱动的标本生成器
最后,您可以撰写{{3}}:
var fixture = new Fixture();
fixture.Customize<User>(c => c
.With(x => x.Email, string.Format("{0}@fobar.com", fixture.Create<string>())
.With(x => x.FullName, fixture.Create<string>().Substring(0,20)));
var newAnon = fixture.Create<User>();
我非常喜欢这种方法,因为我可以在这里放置任意复杂的逻辑,因此我不需要创建大量的一次性自定义,而是可以通过一小组约定来驱动整个测试套件。这也有助于使目标代码更加一致。