强制AutoFixture使用最贪婪的构造函数
我有一个包含多个构造函数的数据类型,我需要AutoFixture来选择最贪婪的(一个参数最多的)。 默认行为是选择编号最小的构造函数。
作者的博客文章http://blog.ploeh.dk/2009/03/24/HowAutoFixtureCreatesObjects.aspx似乎并不意味着有一种方法可以覆盖这种行为,所以它是否可能,如果是这样,如何?
这当然是可能的 。
要更改单个类型( MyClass
)的策略:
fixture.Customize(c => c.FromFactory( new MethodInvoker( new GreedyConstructorQuery())));
全面改变策略:
fixture.Customizations.Add( new MethodInvoker( new GreedyConstructorQuery()));
然而,事实certificate,使用GreedyConstructorQuery全面使用很可能是有问题的,如下面的代码片段所示。 想象一下这个构造函数的类:
public Foo(string name) { this.name = name; }
此测试将抛出exception:
[Test] public void GreedyConstructor() { Fixture fixture = new Fixture(); fixture.Customizations.Add(new MethodInvoker(new GreedyConstructorQuery())); Foo foo = fixture.CreateAnonymous(); }
抛出的exception是:
Ploeh.AutoFixture.ObjectCreationException:AutoFixture无法从System.SByte *创建实例,很可能是因为它没有公共构造函数,是抽象或非公共类型。
那么关于SByte *的是什么? 在Foo中没有SByte *
嗯,是的。 通过将MethodInvoker置于Customization中,它将覆盖所有默认创建策略,包括用于字符串的策略。 相反,它寻找字符串最贪婪的构造函数,那就是:
public String(sbyte* value, int startIndex, int length, Encoding enc);
还有sbyte * ……
用贪婪的算法替换适度的构造函数选择算法仍然是可能的,它比我最初意识到的要多一点。
你能做的是:
写一个像这样的小class:
public class GreedyEngineParts : DefaultEngineParts { public override IEnumerator GetEnumerator() { var iter = base.GetEnumerator(); while (iter.MoveNext()) { if (iter.Current is MethodInvoker) yield return new MethodInvoker( new CompositeMethodQuery( new GreedyConstructorQuery(), new FactoryMethodQuery())); else yield return iter.Current; } } }
并创建像这样的Fixture实例:
Fixture fixture = new Fixture(new GreedyEngineParts());
这应该工作。
- 我应该使用AutoFixture来测试我的洋葱的核心元素,它没有依赖性吗?
- AutoFixture:配置Open Generics Specimen Builder
- AutoFoture与AutoMoq和具体对象注入
- 如何创建始终在AutoFixture中设置预定义值的类列表?
- 如何使用Moq和Autofixture模拟entity framework6
- AutoFixture作为Automocking容器与Automocking差异?
- AutoFixture:PropertyData和异构参数
- AutoFixture可以在对象创建时执行委托吗?
- 如何让Autofixture创建一个包含接口类型属性的类型的实例?