为什么我们的测试方法参数中的类型实例化不完整 - AutoFixture with AutoData
Why do we have incomplete instantiation of types from the test method parameter - AutoFixture with AutoData
使用 Autofixture.xUnit2 3.46 和 xunit2 中的 Autofixture 3.46 AutoData 属性,在测试方法参数中实例化 Sum,我从断言中得到一个 Xunit.sdk.EqualException。
[Theory ]
[AutoData]
public void ShouldBeSum_AutoData(int a, int b, Sum uut )
{
//problem
int residue = uut.Value; //not zero!
//fix
uut.Value = 0;
//Arrange - in the parameter leads to problem
// var uut =new Sum();
//Act
uut.Add(a);
uut.Add(b);
//Assert
Assert.Equal(a + b, uut.Value);
}
似乎新 Sum 实例的 属性 值在实例化时未设置为类型的默认值(比如零)- 证明 'residue' 的非零值。
public class Sum
{
public int Value { get; set; }
public void Add(int number)
{
Value += number;
}
}
从主体(和新的)实例化测试目标 uut 给出了预期的默认初始 属性 值。
因此 uut class 目前未完全从参数实例化 - 这是您的责任。
正在修复?
此行为是设计使然。 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
class 的不变量不应该是 Value
保证 是使用 class 执行计算的结果(即通过调用 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。
使用 Autofixture.xUnit2 3.46 和 xunit2 中的 Autofixture 3.46 AutoData 属性,在测试方法参数中实例化 Sum,我从断言中得到一个 Xunit.sdk.EqualException。
[Theory ]
[AutoData]
public void ShouldBeSum_AutoData(int a, int b, Sum uut )
{
//problem
int residue = uut.Value; //not zero!
//fix
uut.Value = 0;
//Arrange - in the parameter leads to problem
// var uut =new Sum();
//Act
uut.Add(a);
uut.Add(b);
//Assert
Assert.Equal(a + b, uut.Value);
}
似乎新 Sum 实例的 属性 值在实例化时未设置为类型的默认值(比如零)- 证明 'residue' 的非零值。
public class Sum
{
public int Value { get; set; }
public void Add(int number)
{
Value += number;
}
}
从主体(和新的)实例化测试目标 uut 给出了预期的默认初始 属性 值。 因此 uut class 目前未完全从参数实例化 - 这是您的责任。
正在修复?
此行为是设计使然。 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
class 的不变量不应该是 Value
保证 是使用 class 执行计算的结果(即通过调用 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。