我有一个非常简单的单元测试,它正在测试通用List<SelectListItem>
的正确生成。
[TestMethod()]
public void PopulateSelectListWithSeperateTextAndValueLists()
{
//Arrange
SetupDisplayAndValueLists();
bool allOption = false;
//Act
List<SelectListItem> result = ControllerHelpers.PopulateSelectList(valueList, displayList, allOption);
//Assert
Assert.AreEqual(expected, result);
}
Assert总是返回false,即使我已经检查并确认两个对象具有相同的确切值。
当单元测试返回泛型的结果时是否有任何特殊注意事项?
更新了新测试及其状态
Assert.AreEqual(4, result.Count); //passes
Assert.AreEqual(result[0].Text, expected[0].Text, "0 element is not found");//passes
Assert.AreEqual(result[1].Text, expected[1].Text, "1 element is not found");//passes
Assert.AreEqual(result[2].Text, expected[2].Text, "2 element is not found");//passes
Assert.AreEqual(result[3].Text, expected[3].Text, "3 element is not found");//passes
Assert.AreEqual(result[0].Value, expected[0].Value, "0 element is not found");//passes
Assert.AreEqual(result[1].Value, expected[1].Value, "1 element is not found");//passes
Assert.AreEqual(result[2].Value, expected[2].Value, "2 element is not found");//passes
Assert.AreEqual(result[3].Value, expected[3].Value, "3 element is not found");//passes
Assert.IsTrue(result.Contains(expected[0]), "0 element is not found"); //doesn't pass
Assert.IsTrue(result.Contains(expected[1]), "1 element is not found"); //doesn't pass
Assert.IsTrue(result.Contains(expected[2]), "2 element is not found"); //doesn't pass
Assert.IsTrue(result.Contains(expected[3]), "3 element is not found"); //doesn't pass
Assert.AreEqual(expectedList, result); //doesn't pass
答案 0 :(得分:3)
使用CollectionAssert类而不是Assert类。您可以选择验证项目的顺序是否相同,或者只是它们的整体项目相同。
同样,如果您的集合中的项目是引用类型而不是值类型,则可能无法按照您的需要进行比较。 (虽然字符串可以正常工作)
更新:由于您要比较这些项的.Text属性,因此可以尝试使用LINQ将Text属性作为集合返回。然后,CollectionAssert将完全按照您的意愿工作,以比较Text的实际和预期集合。
答案 1 :(得分:0)
这里的问题可能与泛型无关,而是与实现2个列表的相等性有关。列表上的Equals()可以是Object实现,检查它是否只是相同的实例,而不是比较内容。
当我需要测试列表的内容已经按照预期使用C#和mbUnit填充时,我倾向于检查计数是否相等,然后检查列表中的每个项目。或者,如果我不关心结果列表中项目的顺序,我可以检查它是否包含每个项目。
Assert.AreEqual(3, result.Count);
Assert.Contains(expectedList[0], result);
Assert.Contains(expectedList[1], result);
Assert.Contains(expectedList[2], result);
修改强>
看起来像SelectListItem使用Object.Equals()
实现,并且只检查引用相等(相同的实例)。我想到了两种解决方案。
编写一个方法来检查列表是否包含具有给定文本和值的项目,然后重用该项目。它有点干净,但不是很大,除非你有更多的测试。
使用linq语句从结果列表中选择所有文本和所有值。然后使用带有CollectionEquivalentConstraints的Asserts来检查列表是否相等。 (注意我自己没有对此进行过测试,并且正在使用在线文档)。
var texts = result.Select(x =&gt; x.Text).ToList();
var values = result.Select(x =&gt; x.Value).ToList();
Assert.That(texts,Is.EquivalentTo(new string [] {expectedList [0] .Text,expectedList [1] .Text,...}); Assert.That(values,Is.EquivalentTo(new string [] {expectedList [0] .Value,expectedList [1] .Value,...});
您还可以通过将预期值生成为2个单独的列表来显着简化此操作。您可能还会生成Dictionary
,并提供Keys
和Values
作为等效列表。
答案 2 :(得分:0)
Dim i As Integer
Assert.AreEqual(expected.Count, actual.Count)
For i = 0 To expected.Count - 1
Assert.AreEqual(expected.ToList.Item(i).ID, actual.ToList.Item(i).ID)
Next
在这种情况下,我正在比较ID,我想你可以比较任何值类型的键字段并得到相同的。这传递了,而没有任何CollectionAssert方法对我有任何帮助。
Lisa Morgan