【发布时间】:2013-02-01 02:59:51
【问题描述】:
我编写了以下自定义,并将其作为组合的一部分应用于我的大多数测试。我的实体有一个只读 Id,但我在此自定义中使用他们的 SetId 方法来确保所有实体都有一些 Id,如果它们是临时的(还没有 Id)。
public class SetEntityIdCustomization : ICustomization {
public void Customize(IFixture fixture) {
var engine = ((Fixture)fixture).Engine;
fixture.Customizations.Add(new Postprocessor(
engine, o => {
var entity = o as BaseEntity;
if (entity == null || !entity.IsTransient()) {
return;
}
entity.SetId(fixture.CreateAnonymous<Guid>());
}));
}
}
这一直很好,直到我今天发现了一件非常奇怪的事情。如果我提供一个直接从 BaseEntity 继承的实体的测试,那么一切都很好,并且它的可写属性是自动填充的。但是,如果我要求一个从 BaseEntity 更远的东西继承的实体,我的自定义会阻止属性自动填充。
此测试方法中的User实体填充正确:
public class User : BaseEntity {
public string Email { get; set; }
public int CoolThings { get; set; }
}
...
[Theory, AutoDomainData]
public void SomeTest(User user, ...) {
// user.Email and user.CoolThings have auto-filled values, as expected.
...
}
但是,以下测试中的 AwesomeUser 实体没有自动填充任何相同的属性。
public class AwesomeUser : User {
...
}
...
[Theory, AutoDomainData]
public void SomeOtherTest(AwesomeUser user, ...) {
// user.Email nor user.CoolThings have auto-filled values. What gives?
...
}
在这两个测试用例中,由于我的自定义,Id 属性是自动填充的。如果我删除我的自定义,SomeOtherTest 的 AwesomeUser 实例会自动填充其继承的属性。我必须假设是我的自定义搞砸了。
有没有更好的方法让我的所有 BaseEntity 实例设置它们的 ID,或者 AutoFixture 还缺少什么?我首先、中间和最后应用了我的自定义设置,但无济于事。
【问题讨论】:
-
这次this post processor还有用吗?
-
如此处所述,我无法重现此问题...事实上,在我尝试重现此问题时,
User也没有自动填充值...跨度> -
@RubenBartelink 我试过你的后处理器。我看到的结果与我的自定义相同。
-
@MarkSeemann 应该我的自定义“劫持”AutoFixture 的代码,使其不提供
User或AwesomeUser实例的值? -
我对@987654328@ 不太熟悉。我知道它最终被用于
Create一个值。如您所见,我的自定义获取了夹具的引擎并将其用作Postprocessor的样本构建器。我感觉这就是问题所在。相反,我是否应该创建自己的ISpecimenBuilder来生成任何BaseEntity的 Id,然后以某种方式让 AutoFixture 使用实例的其余属性“做它的事情”?