为什么我们从测试方法参数 - AutoFixture with AutoData中对类型进行了不完整的实例化

时间:2016-05-30 21:12:40

标签: c# autofixture

使用Autofixture 3.46 AutoData属性来自Autofixture.xUnit2 3.46和xunit2,在测试方法参数中实例化Sum,我从Assert中得到一个Xunit.sdk.EqualException。

public class Sum
{
    public int Value { get; set; }

    public void Add(int number)
    {
        Value += number;
    }
}

在实例化时,似乎新Sum实例的属性值未设置为类型(例如零)的默认值 - 证明'residual'的非零值。

from snowballstemmer import stemmer
ar_stemmer = stemmer("arabic")
sentence = u"مكتبة لمعالجة الكلمات العربية وتجذيعها"
for word in sentence.split(" "):
    stem = ar_stemmer.stemWord(word)
    print stem

从body(和new)实例化测试目标uut给出了预期的默认初始属性值。 因此,uut类目前尚未完全从参数中实例化 - 这是你的责任。

路上的修复?

1 个答案:

答案 0 :(得分:2)

此行为是设计使然。 AutoFixture旨在创建并将数据填充到对象中,这是它的默认行为。

有许多方法可以在AutoFixture中禁用 AutoProperties 。在此特定示例中,最轻微的修复是将[NoAutoProperties]属性应用于uut参数:

[Theory, AutoData]
public void ShouldBeSum_AutoData(int a, int b, [NoAutoProperties]Sum uut)
{
    uut.Add(a);
    uut.Add(b);

    Assert.Equal(a + b, uut.Value); // Passes
}

但是,还有其他更多批发方法可以达到相同的效果。

最后,这应该暂停以反映Sum的设计:Value是可公开修改的财产是否恰当? Sum类的不变量不应该是Value 保证是使用类执行计算的结果(即通过调用Add)?

这样的设计可能如下所示:

public class Summer
{
    public int Value { get; private set; }

    public void Add(int number)
    {
        Value += number;
    }
}

在这种情况下,以下测试会自动通过:

[Theory, AutoData]
public void ShouldBeSum_AutoData(int a, int b, Summer uut)
{
    uut.Add(a);
    uut.Add(b);

    Assert.Equal(a + b, uut.Value); // Passes
}

AutoFixture最初是作为测试驱动开发(TDD)的工具而构建的,TDD完全是关于反馈的。本着GOOS的精神,你应该倾听你的测试。如果测试难以编写,则应考虑API设计。 AutoFixture倾向于放大这种反馈,因此对AutoFixture问题的良好反应是在查看AutoFixture本身之前查看SUT。