C# 使用FromSeed自定义自动定影会导致异常
鉴于这两类:C# 使用FromSeed自定义自动定影会导致异常,c#,unit-testing,autofixture,C#,Unit Testing,Autofixture,鉴于这两类: class Foo { ... } class Bar { public Foo FooBar { get; set; } } 我已设置以下测试: void Test() { var fixture = new Fixture(); fixture.Customize<Foo>(x => x.FromSeed(TestFooFactory)); var fooWithoutSeed = fixture.Create&
class Foo
{
...
}
class Bar
{
public Foo FooBar { get; set; }
}
我已设置以下测试:
void Test()
{
var fixture = new Fixture();
fixture.Customize<Foo>(x => x.FromSeed(TestFooFactory));
var fooWithoutSeed = fixture.Create<Foo>();
var fooWithSeed = fixture.Create<Foo>(new Foo());
var bar = fixture.Create<Bar>(); //error occurs here
}
Foo TestFooFactory(Foo seed)
{
//do something with seed...
return new Foo();
}
void测试()
{
var fixture=新fixture();
定制(x=>x.FromSeed(TestFooFactory));
var fooWithoutSeed=fixture.Create();
var fooWithSeed=fixture.Create(new Foo());
var bar=fixture.Create();//此处发生错误
}
Foo测试Foo工厂(Foo种子)
{
//用种子做点什么。。。
返回新的Foo();
}
我可以使用种子值和不使用种子值直接创建Foo
对象,没有任何问题。但一旦我尝试创建一个具有Foo
属性的Bar
对象,我就会得到一个ObjectCreationException
:
ISpecimenBuilder无法基于以下请求创建样本:Foo。如果请求表示接口或抽象类,则可能发生这种情况;如果是这种情况,请注册一个ISpecimenBuilder,它可以根据请求创建样本。如果在强类型生成表达式中发生这种情况,请尝试使用IFactoryComposer方法之一提供工厂
我希望testfoodfactory
在创建Bar
的过程中传递null
种子值,就像我在没有种子值的情况下创建Foo
一样。是我做错了什么,还是这是一个错误
在我的真实场景中,我希望自定义在传入种子值时AutoFixture如何为某些对象使用种子值,但如果未提供种子,我仍然希望AutoFixture默认为正常行为。自定义
夹具的方式以使用种子值
您看到的行为是FromSeed
自定义如何修改AutoFixture管道的结果。如果你有兴趣阅读这些细节,我已经描述过了
作为一种解决方法,您可以使用自定义样本生成器处理种子请求,如下所示:
public class RelaxedSeededFactory<T> : ISpecimenBuilder
{
private readonly Func<T, T> create;
public RelaxedSeededFactory(Func<T, T> factory)
{
this.create = factory;
}
public object Create(object request, ISpecimenContext context)
{
if (request != null && request.Equals(typeof(T)))
{
return this.create(default(T));
}
var seededRequest = request as SeededRequest;
if (seededRequest == null)
{
return new NoSpecimen(request);
}
if (!seededRequest.Request.Equals(typeof(T)))
{
return new NoSpecimen(request);
}
if ((seededRequest.Seed != null)
&& !(seededRequest.Seed is T))
{
return new NoSpecimen(request);
}
var seed = (T)seededRequest.Seed;
return this.create(seed);
}
}
当填充类型为Foo
的属性时,此定制将传递default(Foo)
——即null
——作为TestFooFactory
工厂函数的种子,并交叉发布到GitHub:这就像一个符咒!感谢您的解决方案。我用更好的方法更新了自定义RelaxedSeedFactory
样本生成器。它不会处理所有请求,而是只处理T
的种子和非种子请求。作为更新,AutoFixture 3.36.12修复了此问题:。谢谢@Enrico!
fixture.Customize<Foo>(c => c.FromFactory(
new RelaxedSeededFactory<Foo>(TestFooFactory)));