Autofixture可以枚举所有给定每个属性的可能值列表的对象

时间:2014-09-11 14:50:44

标签: c# tdd autofixture

我正处于TDD的中间,可以根据属性过滤对象。过滤规则很多,每个都经常考虑多个属性。

我开始检查每个规则,通过提供它们被过滤的所有对象属性的枚举,但这很快就变得无趣了,我想在我的大脑被“复制 - 粘贴degenerescence”吃掉​​之前解决疼痛。

在这种情况下,

AutoFixture 应该非常有用,但我无法在FAQ或CheatSheet中找到这些信息。 Ploeh的博客populated lists看起来很有前景,但对我来说还不够深入。

所以,给定以下课程

public class Possibility
{
    public int? aValue {get;set;}
    public int? anotherValue {get;set;}
}

我是否可以获得Possibility的列表,其中每个类包含一个可能的预定义值aValueanotherValue的枚举?例如,给定[null, 10, 20]的值aValue[null, 42]的{​​{1}},我将返回anotherValue的6个实例。

如果不是,我怎么能在每个对象类型自己编码之外得到这种行为?

2 个答案:

答案 0 :(得分:4)

给出问题的值:

  • null1020 aValue
  • null42-- anotherValue

以下是使用Generator<T>

在AutoFixture中执行此操作的一种方法
[Fact]
public void CustomizedAutoFixtureTest()
{
    var fixture = new Fixture();
    fixture.Customizations.Add(
        new PossibilityCustomization());

    var possibilities = 
        new Generator<Possibility>(fixture).Take(3);

    // 1st iteration
    // -------------------
    // aValue       | null
    // anotherValue | null 

    // 2nd iteration
    // -------------------
    // aValue       | 10
    // anotherValue | 42

    // 3rd iteration
    // -------------------
    // aValue       | 20
    // anotherValue | (Queue is empty, generated by AutoFixture.)
}

PossibilityCustomization在内部使用Queue类来提供预定义值 - 当它用完预定义值时,它使用AutoFixture。

private class PossibilityCustomization : ISpecimenBuilder
{
    private readonly Queue<int?> aValues = 
                 new Queue<int?>(new int?[] { null, 10, 20 });

    private readonly Queue<int?> anotherValues =
                 new Queue<int?>(new int?[] { null, 42 });

    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as PropertyInfo;
        if (pi != null)
        {
            if (pi.Name == "aValue" && aValues.Any())
                return aValues.Dequeue();

            if (pi.Name == "anotherValue" && anotherValues.Any())
                return anotherValues.Dequeue();
        }

        return new NoSpecimen();
    }
}

答案 1 :(得分:4)

AutoFixture会生成Anonymous Values,因此当您已经拥有要组合的精确值时,它可能不是完全胜任该工作的正确工具。

如果您使用的是NUnit,则可以改为:

[Test]
public void HowToGetPermutations(
    [Values(null, 10, 20)] int? aValue,
    [Values(null, 42)] int? anotherValue)
{
    // Test and assert
}

这将运行此测试方法六次 - 每种可能的排列一次。

这是我希望xUnit.net拥有的少数几项功能之一,但它没有......