I have a query very similar to this:
var result = context.EntityRole
.Where(er => er.EntityType.EntityTypeId == entityTypeIdParameter
&& er.Entity.SomeItems.Any(item => item.ItemId == itemIdParameter))
.ToList()
.Distinct(customItemComparer)
.OrderBy(er => er.Id)
.ThenByDescending(er => er.IsApproved)
.ToList();
The customItemComparer would be something similar to this:
public class CustomItemComparer : IEqualityComparer<EntityRole>
{
public bool Equals(EntityRole x, EntityRole y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;
return x.Property1 == y.Property1
&& x.Property2 == y.Property2
&& x.Property3 == y.Property3;
}
public int GetHashCode(EntityRole obj)
{
if (ReferenceEquals(obj, null)) return 0;
var hasProperty1 = obj.Property1.GetHashCode();
var hasProperty2 = obj.Property2.GetHashCode();
var hasProperty3 = obj.Property3.GetHashCode();
return hasProperyt1 ^ hasProperty2 ^ hasProperty3;
}
}
The problem that I have is that when I run the application I get the expected results and apparently all the different scenarios work flawlessly, but when I try unit testing it the query always returns a single object even though the list contains more than one objects whose properties 1, 2, and 3 are different.
My unit test looks something like this, we are using MOQ, other properties removed for brevity:
var roles = new List<EntityRole>
{
new EntityRole
{
Property1 = true,
Property2 = 5,
Property3 = "something"
},
new EntityRole
{
Property1 = true,
Property2 = 9,
Property3 = "something"
},
new EntityRole
{
Property1 = false,
Property2 = 5,
Property3 = "something"
},
new EntityRole
{
Property1 = true,
Property2 = 5,
Property3 = "something else"
}
}
contextMock.Setup(c => c.EntityRole).Returns(roles.AsQueryable);
var sut = new SubjectUnderTest();
sut.MethodWhereQueryIsExecuted();
//some code to verify results
So like I said, even though there are no two objects identical in the list, the query always returns the first one.
Also if I put break points in the CustomItemComparer, the execution stops when running the application but it never stops when debugging the test.
So the exact question would be why is the Distinct working perfectly when the application is run and it does not work when the unit test is run?
I ran into the same problem while using MOQ with Distinct, which was working fine in production but was failing miserably in tests. It seems distinct doesn't work as expected with objects which are of type Mock<>.Object apparently.
In my scenario, I opted to use DistinctBy extension from MoreLINQ. If you want to use just Linq, then you can use GroupBy and take the first of each group instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With