Reputation: 324
I've got an injected interface I'm unit testing. The method in question is working, but I'm trying to write a unit test that confirms the returned sample data is complete and accurate. My test looks correct to me, and even the results look identical, yet the test fails with "CollectionAssert.AreEquivalent failed. The expected collection contains 1 occurrence(s) of . The actual collection contains 0 occurrence(s)."
[TestMethod]
public void Should_Get_All_Amenities()
{
var amenitiesRep = _ninjectKernel.Get<IAmenityRepository>();
var amenities = amenitiesRep.GetAmenities();
var expected = new List<Amenity>
{
new Amenity() {Id = 1, Name = "Pool", Category = "resort"},
new Amenity() {Id = 2, Name = "Hottub", Category = "resort"},
new Amenity() {Id = 3, Name = "Steamroom", Category = "unit"}
};
Assert.IsNotNull(amenities);
Assert.IsTrue(amenities.Count() == 3);
CollectionAssert.AreEquivalent(expected, amenities);
}
(Relevant code from my TestRepository)
var amenities = new List<Amenity>
{
new Amenity() {Id = 1, Name = "Pool", Category = "resort"},
new Amenity() {Id = 2, Name = "Hottub", Category = "resort"},
new Amenity() {Id = 3, Name = "Steamroom", Category = "unit"}
};
var mockAmenitiesRep = new Mock<IAmenityRepository>();
mockAmenitiesRep.Setup(_m => _m.GetAmenities()).Returns(amenities);
Kernel.Bind<IAmenityRepository>().ToConstant(mockAmenitiesRep.Object);
I can confirm at all the data is populated correctly at the CollectionAssert, every field appears to match 1 to 1, same number of objects, same object types, so I'm just lost why the test is failing.
(Edit: Line the code fails on is the CollectionAssert)
Upvotes: 2
Views: 6335
Reputation: 38468
It's because Amenity is a reference type so CollectionAssert.AreEquivalent checks equality by referenced addresses. Since the items in the expected collection are not the same objects you get from GetAmenities() method, it returns false. You have to override equality comparers in Amenity class.
public override bool Equals(object obj)
{
var other = obj as Amenity;
if(other == null)
{
return false;
}
return Id = other.Id && Name == other.Name && Category == other.Category;
}
public override int GetHashCode()
{
return Id.GetHashCode(); //assumes Id is immutable
}
Update:
Keep in mind this approach is not very good because it leads to Equality Pollution. Alexander Stepaniuk posted a better alternative in comments.
Upvotes: 9