簡體   English   中英

強制AutoFixture使用最貪婪的構造函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM