Autofixture: SemanticComparison - Likeness of Two Child Collections

Created on 21 Jun 2017  ·  13Comments  ·  Source: AutoFixture/AutoFixture

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 class right out of the box was gonna fix this, but it crapped out on the collections even though they contained identical items.

question

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.

All 13 comments

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

  • One DelegatingMemberComparer for all types, which does a.Equals(b) or even uses Likeness for it
  • One DelegatingMemberComparer for IEnumerable<TagDto> as shown in that link above

in 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!

Was this page helpful?
0 / 5 - 0 ratings