c# – 如何在本单元测试中避免多个断言?

前端之家收集整理的这篇文章主要介绍了c# – 如何在本单元测试中避免多个断言?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我第一次尝试进行单元测试,所以请耐心等待我.
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的每个属性.
我读了很多次,一次测试中多次断言是邪恶的(我明白为什么,我同意的原因).

问题是如何摆脱他们?

我有Roy 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();

我也不喜欢这个,因为这实际上是在实际的转换方法(被测方法)中的一些代码的重复,这是测试中另一回事.

那么我该怎么办?
在这种特殊情况下,这种复制水平是否仍然可以接受,还是有更好的方法来测试呢?

解决方法

我认为,在这件事的精神上,这是很好的.多重断言是“邪恶”的原因,如果我记得正确的是,它意味着你在一次测试中测试多个东西.在这种情况下,您确实在做,因为您正在测试每个字段,大概是为了确保这适用于几种不同的类型.既然这样,所有的对象平等测试都会做,反正我觉得你很清楚.

如果你真的想要武装,那么每个属性写一个测试(j / k!)

猜你在找的C#相关文章