I'm sure this has been asked before, and I've googled this and found some complex solutions, but here goes anyway. I have two complex objects of exactly the same type and I want to compare them; however, they contain a collection of items that also need to be compared, but I want to ignore order. Is this possible with SemanticComparison? I'm currently using a json comparison mechanism, but debugging this when the compares fail is a nightmare. It looked like using the Likeness
Can you show us how the object you're trying to compare looks like?
Also, have you tried using the SemanticComparer<T>
directly as shown in this example? This is more flexible than using Likeness<TSource, TDestination>
.
The object has this structure:
public class SongDto
{
public string Lyrics { get; set; }
public IEnumerable<TagDto> Tags { get; set; }
public string FileName { get; set; }
public string CustomPromoLink { get; set; }
public string UPC { get; set; }
public YoutubeVideoDto YouTubeVideo { get; set; }
}
The two properties it hiccuped on were the TagDto collection and the YouTubeVideoDto, ideally it would traverse these and keep comparing as deep as they went. Otherwise I'm going to stick with my JSON comparer as this way of comparing is going to make me do a bunch of work anyway.
I'd be curious to find out how that JSON comparer handles IEnumerable<TagDto>
if it's an infinite sequence?
How would anything handle an infinite sequence? I'm certainly not saying it's perfect, and I'm obviously looking for another solution hence the dive into SemanticComparison, but if SC can't handle this situation, then I simply don't see the point in using it. I'm assuming there is a way to handle this, I just couldn't find a good solution out there on the ole interwebs.
You can do similar to this, by using a DelegatingMemberComparer
that either returns always True
for IEnumerable<TagDto>
or, even better, compares IEnumerable<TagDto>
in the way you want.
(See the second and third DelegatingMemberComparer
instance in the above link.)
Okay, thank you sincerely for the help.
So in essence, I still have to write a custom DelegatingMemberComparer for each type. So then the advantage of using the library is that in a failing test it tells me what properties are different?
I still have to write a custom DelegatingMemberComparer for each type
DelegatingMemberComparer
for all types, which does a.Equals(b) or even uses Likeness for itDelegatingMemberComparer
for IEnumerable<TagDto>
as shown in that link abovein a failing test it tells me what properties are different
No, that's what Likeness does...
Likeness uses SemanticComparer<T>
internally to compare objects... So, if you're going to use SemanticComparer<T>
you may be more flexible but you'll loose the reporting feature of Likeness.
If you do need the reporting stuff, you might be able to achieve something similar using Likeness's With
and EqualsWhen
syntax as shown in this example.
Okay, now I'm back to my original question, what do I get from this library if the reporting stuff is no longer there (from what I've read Likeness is going to be deprecated), and if write a DelegatingMemberComparer that does a.Equals(b), it's going to do a reference comparison or I have to override every object's Equals method. Is that right?
So what's the gain over using xUnit Assert with IEqualityComparers?
I'd just like to add that I think AutoFixture is amazing, and I figured SemanticComparer would make my asserts as easy as my setups.
I'll try to provide 3 examples (Likeness, SemanticComparer, IEqualityComparer) for your SongDto
so we may continue discussing from there.—I'm swamped with work at the moment, so it might take me a while...
@moodmosaic Thanks a ton!! And if you'd like to point me towards some articles that explain the whys whats of SemanticComparer, maybe that would make me less dense on this point.
For these scenarios, I've used the https://github.com/jmansar/SemanticComparisonExtensions with great effect. With that, I can control the inner likenesses and tweak things a bit.
Makes an excellent way to quickly setup complex nested comparisons, too.
@cvbarros Those extensions worked like a charm, closing this issue!
Most helpful comment
For these scenarios, I've used the https://github.com/jmansar/SemanticComparisonExtensions with great effect. With that, I can control the inner likenesses and tweak things a bit.
Makes an excellent way to quickly setup complex nested comparisons, too.