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

sam*_*amy 2 c# tdd autofixture

我正处于 TDD-ing 业务类的中间,该业务类可以根据对象的属性过滤对象。过滤规则很多,每个规则通常考虑多个属性。

我开始通过提供所有对象属性的枚举来检查每个规则,但是这很快变得无趣,我想在我的大脑被“复制粘贴退化”吃掉之前解决这个痛苦。

AutoFixture在这种情况下应该会很有帮助,但我在 FAQ 或 CheatSheet 中都找不到相关信息。Ploeh 的博客填充列表看起来很有希望,但对我来说不够深入。

所以,给定以下课程

public class Possibility
{
    public int? aValue {get;set;}
    public int? anotherValue {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我能得到的列表Possibility,每个类包含一个预定义值可能枚举aValueanotherValue?例如,给定[null, 10, 20]foraValue[null, 42]for的值anotherValue,我将返回 6 个Possibility.

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

Nik*_*nis 5

鉴于问题中的值:

  • null, 10,20 对于aValue
  • null, 42,--对于anotherValue

这是使用 AutoFixture 执行此操作的一种方法,使用Generator<T>

[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.)
}
Run Code Online (Sandbox Code Playgroud)

在内部,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();
    }
}
Run Code Online (Sandbox Code Playgroud)