VS 单元测试看不到预期结果和实际结果相等



我们将在不久的将来转向TDD风格的开发,所以我正在尝试VS 2013附带的VS单元测试(这是我们在工作中使用的(。 我正在尝试使用 TDD 编写一个可以找到 Kaprekar 常量的类。 我正处于开发阶段,我有一个提交有效数字的测试,我希望有一个包含返回一个元素的列表。 该元素将由一个 3 单元格数组组成。 这三个单元格将包含原始数字、数字按降序排列的数字和数字按升序排列的数字。 我的调试代码显示我得到了预期的结果,但单元测试说我没有。 我需要做什么才能让单元测试看到预期结果和实际结果相等? 这是我代码的删节版。

单元测试代码:

namespace KaprekarsConstantTest
{
[TestClass]
public class UnitTest1
{
private Kaprekar k;
[TestInitialize]
public void Init()
{
k = new Kaprekar();
}
[TestMethod]
public void FirstRow()
{
int[] row = new int[3];
row[0] = 5324;
row[1] = 5423;
row[2] = 2345;
List<int[]> expected = new List<int[]>();
expected.Add(row);
List<int[]> actual = k.Generate(5324);
int[] rslt = actual[0];
int[] expct = expected[0];
CollectionAssert.AreEqual(expected, actual,
"nExpect: " + expct[0].ToString() + "; " + expct[1].ToString() + "; " + expct[2].ToString() +
"nActual: " + rslt[0].ToString() + "; " + rslt[1].ToString() + "; " + rslt[2].ToString() + "n");
}
}
}

应用程序代码

namespace KaprekarsConstant
{
public class Kaprekar
{
public List<int[]> Generate(params int[] orgNum)
{
List<int[]> rtnVal = new List<int[]>();
int num = orgNum[0];
string digits = num.ToString();
int[] row = new int[3];
row[0] = num;
List<int> lstDigits = new List<int>();
string snglNum = String.Empty;
for (int ndx = 0; ndx < 4; ndx++)
{
snglNum = digits[ndx].ToString();
lstDigits.Add(int.Parse(snglNum));
}
lstDigits.Sort();
string dNum = String.Empty;
for (int ndx = 3; ndx > -1; ndx--)
dNum = dNum + lstDigits[ndx].ToString();
row[1] = int.Parse(dNum);
string aNum = String.Empty;
for (int ndx = 0; ndx < 4; ndx++)
aNum = aNum + lstDigits[ndx].ToString();
row[2] = int.Parse(aNum);
rtnVal.Add(row);
return rtnVal;
}
}
}

测试结果

测试名称:第一行

测试全名:KaprekarsConstantTest.UnitTest1.FirstRow

测试源:*...\项目\C_Sharp\KaprekarsConstant\KaprekarsConstantTest\UnitTest1.cs : 第 51 行

测试结果:失败

测试持续时间:0:00:00.0033773

结果消息:CollectionAssert.AreEqual 失败。

预期: 5324; 5423; 2345

实际: 5324; 5432; 2345

(索引 0 处的元素不匹配。

Result StackTrace:at KaprekarsConstantTest.UnitTest1.FirstRow(( in ...\Projects\C_Sharp\KaprekarsConstant\KaprekarsConstantTest\UnitTest1.cs:line 61

此测试失败的原因有两个:

  • 每个列表的第一个元素(元素 0(是三个元素的数组。它们实际上不匹配 - 第一个元素的第二个元素是 5423和 5432。即使你修复了这个问题,它仍然会失败,因为...

  • 其次,您需要告诉 .NET 对列表的元素进行结构比较,默认情况下它会进行对象引用比较 - 即每个 int[] 数组的引用相等性。

按如下方式更改集合断言:

CollectionAssert.AreEqual(
expected, actual, 
System.Collections.StructuralComparisons.StructuralComparer,
"nExpect: " + ... // omitted for brevity
);

并且测试将通过。

如果您只是比较数组,测试框架进行零碎比较,因此,例如,此测试将通过:

[TestMethod]
public void WillCompareByElement()
{
var x = new[] { 3, 2 };
var y = new[] { 3, 2 };
CollectionAssert.AreEqual(x, y);
}

您可能会获得更清晰的测试失败消息,循环访问列表中的每个元素并以这种方式进行比较。

此外,您可以考虑使用像 Shouldly 这样的体面断言库。然后你可以写:

expected.ShouldBe(actual);

并获得如下输出:

Message: Test method SOTestEquals.UnitTest1.SecondRow threw exception: 
Shouldly.ShouldAssertException: [[5324, 5423, 2345]]
should be
[[5324, 5432, 2345]]
but was not
difference
[*[5324, 5423, 2345]*]

节省编写自定义输出的时间。

最新更新