问题
I am currently trying to learn how to use unit testing, and I have created the actual list of 3 animal objects and the expected list of 3 animal objects. The question is how do I Assert to check the lists are equal? I have tried CollectionAssert.AreEqual and Assert.AreEqual but to no avail. Any help would be appreciated.
The test method:
[TestMethod]
public void createAnimalsTest2()
{
animalHandler animalHandler = new animalHandler();
// arrange
List<Animal> expected = new List<Animal>();
Animal dog = new Dog("",0);
Animal cat = new Cat("",0);
Animal mouse = new Mouse("",0);
expected.Add(dog);
expected.Add(cat);
expected.Add(mouse);
//actual
List<Animal> actual = animalHandler.createAnimals("","","",0,0,0);
//assert
//this is the line that does not evaluate as true
Assert.Equals(expected ,actual);
}
回答1:
Just incase someone comes across this in the future, the answer was I had to create an Override, IEqualityComparer as described below:
public class MyPersonEqualityComparer : IEqualityComparer<MyPerson>
{
public bool Equals(MyPerson x, MyPerson y)
{
if (object.ReferenceEquals(x, y)) return true;
if (object.ReferenceEquals(x, null)||object.ReferenceEquals(y, null)) return false;
return x.Name == y.Name && x.Age == y.Age;
}
public int GetHashCode(MyPerson obj)
{
if (object.ReferenceEquals(obj, null)) return 0;
int hashCodeName = obj.Name == null ? 0 : obj.Name.GetHashCode();
int hasCodeAge = obj.Age.GetHashCode();
return hashCodeName ^ hasCodeAge;
}
}
回答2:
That is correct, as the lists are 2 different objects containing the similar data.
In order to get compare lists you should use the CollectionAssert
CollectionAssert.AreEqual(expected ,actual);
That should do the trick.
回答3:
I am of the opinion that implementing the IEqualityComparer (Equals() and GetHashCode()) for only testing purpose is a code smell. I would rather use the following assertion method, where you can freely define that on which properties you want to do the assertions:
public static void AssertListEquals<TE, TA>(Action<TE, TA> asserter, IEnumerable<TE> expected, IEnumerable<TA> actual)
{
IList<TA> actualList = actual.ToList();
IList<TE> expectedList = expected.ToList();
Assert.True(
actualList.Count == expectedList.Count,
$"Lists have different sizes. Expected list: {expectedList.Count}, actual list: {actualList.Count}");
for (var i = 0; i < expectedList.Count; i++)
{
try
{
asserter.Invoke(expectedList[i], actualList[i]);
}
catch (Exception e)
{
Assert.True(false, $"Assertion failed because: {e.Message}");
}
}
}
In action it would look like as follows:
public void TestMethod()
{
//Arrange
//...
//Act
//...
//Assert
AssertAnimals(expectedAnimals, actualAnimals);
}
private void AssertAnimals(IEnumerable<Animal> expectedAnimals, IEnumerable<Animal> actualAnimals)
{
ListAsserter.AssertListEquals(
(e,a) => AssertAnimal(e,a),
expectedAnimals,
actualAnimals);
}
private void AssertAnimal(Animal expected, Animal actual)
{
Assert.Equal(expected.Name, actual.Name);
Assert.Equal(expected.Weight, actual.Weight);
//Additional properties to assert...
}
I am using XUnit for the simple Assert.True(...) and Assert.Equals(), but you can use any other unit test library for that. Hope it helps someone! ;)
来源:https://stackoverflow.com/questions/19562505/assert-to-compare-two-lists-of-objects-c-sharp