这是我第一次做单元测试,所以请耐心等待。
I'm still trying to unit test a library that converts lists of POCOs to ADO.Recordsets。如何在本单元测试中避免多次断言?
现在,我试图编写一个测试,创建一个List<Poco>
,将它转换成一个Recordset(使用我想测试的方法),然后检查它们是否包含相同的信息(如Poco.Foo == RS.Foo
和等等......)。
这是POCO:
public class TestPoco
{
public string StringValue { get; set; }
public int Int32Value { get; set; }
public bool BoolValue { get; set; }
}
...这是测试至今(我使用xUnit.net):
[Fact]
public void TheTest()
{
var input = new List<TestPoco>();
input.Add(new TestPoco { BoolValue = true, Int32Value = 1, StringValue = "foo" });
var actual = input.ToRecordset();
Assert.Equal(actual.BoolValue, true);
Assert.Equal(actual.Int32Value, 1);
Assert.Equal(actual.StringValue, "foo");
}
我做什么不喜欢这是最后的三个断言,每个POCO的一个属性。
我读过很多次,在一次测试中多重断言是邪恶的(我理解为什么,我同意)。
问题是,我该如何摆脱它们?
我有罗伊Osherove的优秀图书"The Art of Unit Testing"就在我的面前,他有这正好覆盖这(对于那些谁拥有这本书:章7.2.6,202/203页)为例:
在他的示例中,被测方法返回一个带有多个属性的对象AnalyzedOutput
,并且他想要声明所有属性以检查每个属性是否包含期望值。
在这种情况下的解决方案:
创建另一个AnalyzedOutput
例如,与预期值填充它,并断言如果它等于被测该方法返回一个(并且覆盖Equals()
才能够做到这一点)。
但我认为我不能这样做在我的情况下,因为我想测试的方法返回ADODB.Recordset
。
而且为了创造另一个Recordset
与预期值,我首先就需要完全从头开始创建:
// this probably doesn't actually compile, the actual conversion method
// doesn't exist yet and this is just to show the idea
var expected = new ADODB.RecordsetClass();
expected.Fields.Append("BoolValue", ADODB.DataTypeEnum.adBoolean);
expected.Fields.Append("Int32Value", ADODB.DataTypeEnum.adInteger);
expected.Fields.Append("StringValue", ADODB.DataTypeEnum.adVarWChar);
expected.AddNew();
expected.BoolValue = true;
expected.Int32Value = 1;
expected.StringValue = "foo";
expected.Update();
我不喜欢这样,因为这是一些基本的复制的实际转换方法(被测方法)中的代码,这是在测试中要避免的另一件事。
那么...我现在可以做什么?
在这种特殊情况下,这种重复级别仍然可以接受吗?还是有更好的方法来测试?
这就是为什么它是单元测试的“艺术”而不是“科学”...... – Berryl 2012-01-10 00:54:08
在一个测试案例中的多个断言并不是邪恶的。每个测试用例应该只有一个断言的想法[很愚蠢](http://stackoverflow.com/a/20300843/545127)。 – Raedwald 2016-04-05 11:37:56