![](/img/trans.png)
[英]Using GreedyConstructorQuery and AutoMoqCustomization does use greediest constructor and inject dependency
[英]Force AutoFixture to use the greediest constructor
我有一個包含多個構造函數的數據類型,我需要AutoFixture來選擇最貪婪的(一個參數最多的)。 默認行為是選擇編號最小的構造函數。
作者的博客文章http://blog.ploeh.dk/2009/03/24/HowAutoFixtureCreatesObjects.aspx似乎並不意味着有一種方法可以覆蓋這種行為,所以它是否可能,如果是這樣,如何?
這當然是可能的 。
要更改單個類型( MyClass
)的策略:
fixture.Customize<MyClass>(c => c.FromFactory(
new MethodInvoker(
new GreedyConstructorQuery())));
要全面改變策略:
fixture.Customizations.Add(
new MethodInvoker(
new GreedyConstructorQuery()));
然而,事實證明,全面使用GreedyConstructorQuery很可能會出現問題,如下面的代碼片段所示。 想象一下這個構造函數的類:
public Foo(string name)
{
this.name = name;
}
此測試將拋出異常:
[Test]
public void GreedyConstructor()
{
Fixture fixture = new Fixture();
fixture.Customizations.Add(new MethodInvoker(new GreedyConstructorQuery()));
Foo foo = fixture.CreateAnonymous<Foo>();
}
拋出的異常是:
Ploeh.AutoFixture.ObjectCreationException:AutoFixture無法從System.SByte *創建實例,很可能是因為它沒有公共構造函數,是抽象或非公共類型。
那么關於SByte *的是什么? 在Foo中沒有SByte *
嗯,是的。 通過將MethodInvoker置於Customization中,它將覆蓋所有默認創建策略,包括用於字符串的策略。 相反,它尋找字符串最貪婪的構造函數,那就是:
public String(sbyte* value, int startIndex, int length, Encoding enc);
還有sbyte * ......
用貪婪算法替換適度的構造函數選擇算法仍然是可能的,它比我最初意識到的要多一點。
你能做的是:
寫一個像這樣的小班:
public class GreedyEngineParts : DefaultEngineParts
{
public override IEnumerator<ISpecimenBuilder> 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());
這應該工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.