我的课程如下:
public class BaseItem
{
public Guid Id { get; set; }
public Language Language { get; set; }
}
public class ItemA : BaseItem
{
public string Name { get; set; }
}
public class ItemB : BaseItem
{
public string Path { get; set; }
}
每次创建Language
,ItemA
或ItemB
类的任何未来实现时,我都想省略属性BaseItem
。
我在自定义类中添加了这一行(下面),但在生成ItemA
/ ItemB
时, AutoFixture 仍尝试生成Language
属性
fixture.Register<BaseItem>(() => { return fixture.Build<BaseItem>().Without(i => i.Language).Create(); });
在这样的实现类级别上省略属性(见下文)是有效的。
fixture.Register<ItemA>(() => { return fixture.Build<ItemA>().Without(i => i.Language).Create(); });
我的问题是:
答案 0 :(得分:0)
为了定位(或者更确切地说,省略)在基类上定义的属性,我知道没有比定义自定义ISpecimenBuilder
更好的方法,在这种情况下类似于:
public class OmitLanguageBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var pi = request as PropertyInfo;
if (pi != null &&
pi.PropertyType == typeof(Language)
&& pi.Name == "Language"
&& pi.DeclaringType == typeof(BaseItem))
return new OmitSpecimen();
return new NoSpecimen();
}
}
这专门处理仅在Language
上声明的BaseItem
属性的请求。如果您想要不那么具体,可以删除if
表达式中的一些谓词。当AutoFixture收到这样的请求时,它会解释特殊的信号类型&#39; OmitSpecimen
作为忽略该财产的指示。
您可以直接向OmitLanguageBuilder
实例注册Fixture
(尽管您应该将其打包在 Customization 中。此测试通过:
[Fact]
public void Q1A()
{
var fixture = new Fixture();
fixture.Customizations.Add(new OmitLanguageBuilder());
var actual = fixture.Create<ItemA>();
Assert.Null(actual.Language);
Assert.NotEqual(default(Guid), actual.Id);
Assert.NotNull(actual.Name);
}
ItemB
的类似测试也会通过。
如果要在特殊测试用例中填充Language
,最简单的解决方案可能只是在事实之后填充它:
[Fact]
public void Q2SetAfter()
{
var fixture = new Fixture();
fixture.Customizations.Add(new OmitLanguageBuilder());
var actual = fixture.Create<ItemA>();
actual.Language = fixture.Create<Language>();
Assert.NotNull(actual.Language);
Assert.NotEqual(default(Guid), actual.Id);
Assert.NotNull(actual.Name);
}
另一种选择是使用Build
API:
[Fact]
public void Q2Build()
{
var fixture = new Fixture();
fixture.Customizations.Add(new OmitLanguageBuilder());
var actual =
fixture.Build<ItemA>().With(x => x.Language, fixture.Create<Language>()).Create();
Assert.NotNull(actual.Language);
Assert.NotEqual(default(Guid), actual.Id);
Assert.NotNull(actual.Name);
}
最后,如果您需要更改AutoFixture处理类型的方式,您可以执行以下操作:
[Fact]
public void Q2Customize()
{
var fixture = new Fixture();
fixture.Customizations.Add(new OmitLanguageBuilder());
fixture.Customize<ItemA>(c => c.With(x => x.Language, fixture.Create<Language>()));
var actual = fixture.Create<ItemA>();
Assert.NotNull(actual.Language);
Assert.NotEqual(default(Guid), actual.Id);
Assert.NotNull(actual.Name);
}