力AutoFixture用贪婪的构造 [英] Force AutoFixture to use the greediest constructor

查看:198
本文介绍了力AutoFixture用贪婪的构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多个构造数据类型,我需要AutoFixture选择贪婪(一个最参数)。默认行为是选择具有最小号的构造。

I have a data type with multiple constructors and I need AutoFixture to choose the greediest (one with the most parameters). The default behaviour is to choose the constructor with the smallest number.

作者的博客文章,的 http://blog.ploeh.dk/2009/03/24/HowAutoFixtureCreatesObjects.aspx 似乎并不意味着有重写此行为的一种方式,所以是有可能,如果是这样,怎么样?

The author's blog post, http://blog.ploeh.dk/2009/03/24/HowAutoFixtureCreatesObjects.aspx doesn't seem to imply there's a way of overriding this behaviour, so is it possible, and if so, how?

推荐答案

This当然是可能

要改变策略了单一​​类型( MyClass的):

To change the strategy for a single type (MyClass):

fixture.Customize<MyClass>(c => c.FromFactory(
    new MethodInvoker(
        new GreedyConstructorQuery())));

要改变一刀切的策略:

fixture.Customizations.Add(
    new MethodInvoker(
        new GreedyConstructorQuery()));






事实证明,但是,在整个使用GreedyConstructorQuery董事会是最有可能有问题的,如下面的代码片段演示。想象一下,这个构造函数的类:


As it turns out, however, using GreedyConstructorQuery across the board is most likely problematic, as the following code snippet demonstrates. Imagine a class with this constructor:

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>();
}



引发的异常是:

The exception thrown is:

Ploeh.AutoFixture.ObjectCreationException:AutoFixture无法创建System.SByte *一个实例,很可能是因为它没有公共构造,是一个抽象或非公开的类型

Ploeh.AutoFixture.ObjectCreationException : AutoFixture was unable to create an instance from System.SByte*, most likely because it has no public constructor, is an abstract or non-public type.

那么,有什么说关于为SByte *?有Foo中没有为SByte * ...

So what's that about the SByte*? There's no SByte* in Foo...

恩,是的,有。通过将MethodInvoker的定制,它覆盖的所有的默认创建的策略,其中包括一个字符串。相反,它会寻找一个字符串的贪婪的构造函数,那就是:

Well, yes there is. By placing the MethodInvoker in Customization, it overrides all default creation strategies, including the one for strings. Instead, it goes looking for the greediest constructor for string and that is:

public String(sbyte* value, int startIndex, int length, Encoding enc);

和还有的为sbyte * ...

And there's the sbyte*...

它仍然可能的替换的一个贪心算法适度构造选择算法,它只是一点点更多地参与比我第一次意识到。

It's still possible to replace the modest constructor selection algorithm with a greedy algorithm, it's just a tad more involved than I first realized.

你可以做的是这样的:

写小班像这样的:

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;
        }
    }
}

和创建像灯具实例这样的:

and create the Fixture instance like this:

Fixture fixture = new Fixture(new GreedyEngineParts());

这应该工作。

这篇关于力AutoFixture用贪婪的构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆