AutoFixture - Excellent. Comparison of complex objects

I am trying to compare 2 complex objects with AutoFixture OfLikeness, but unfortunately without success. When comparing nested objects (also with OfLikeness) it works as expected, comparing the main object with an error, saying that the child objects do not match. I assume the problem is that Likeness only applies the semantic matching to the main object, and nested objects are compared using the standard Equal implementation, which checks for matching links (maybe my assumption is wrong?).

This may clarify what I'm trying to achieve:

public class ComplexMasterObject{
    public ChildFirst child1 {get;set;}
    public ChildSecond child2 {get;set;}
    public string SimpleProp {get;set;}
}

public class ChildFirst {
    public string SomeStringProp1 {get;set;}
    public int  SomeIntProp1 {get;set;}
}

public class ChildSecond {
    public string SomeStringProp1 {get;set;}
    public int  SomeIntProp1 {get;set;}
}

Test:

public void TestLikeness_Success()
{
     var expected = new ComplexMasterObject {
         Child1 = new ChildFirst {
             SomeStringProp1 = "ChildFirst SomeStringProp1",
             SomeIntProp1 = 1
         },
         Child2 = new ChildSecond {
             SomeStringProp1 = "ChildSecond SomeStringProp1",
             SomeIntProp1 = 2
         },
         SimpleProp = "ComplexMasterObject SimpleProp"
     };

     var input = new ComplexMasterObject {
         Child1 = new ChildFirst {
             SomeStringProp1 = "ChildFirst SomeStringProp1",
             SomeIntProp1 = 1
         },
         Child2 = new ChildSecond {
             SomeStringProp1 = "ChildSecond SomeStringProp1",
             SomeIntProp1 = 2
         },
         SimpleProp = "ComplexMasterObject SimpleProp"
     };

     var child1Likeness = expected.Child1.AsSource().OfLikeness<ChildFirst>();
     var child2Likeness = expected.Child2.AsSource().OfLikeness<ChildSecond>();

     var masterLikeness = expected.AsSource().OfLikeness<ComplexMasterObject>();
     child1Likeness.ShouldEqual(input.Child1); //Passes
     child2Likeness.ShouldEqual(input.Child2); //Passes

     masterLikeness.ShouldEqual(input); 
     // The provided value `ComplexMasterObject` did not match the expected value `ComplexMasterObject`. The following members did not match:
  - Child1.
  - Child2.
}

When I serialize expectedboth inputobjects in JSON and compare the results, they are identical.

"", :

var proxy = expected.AsSource().OfLikeness<ComplexMasterObject>().CreateProxy();
proxy.Equals(input); // returns false

, ?

.

+4
1

# ( ) , .

, , , SemanticComparison , AutoFixture ( NuGet).

: SemanticComparer<T>

[Fact]
public void TestComplexClassEquality()
{
    // Arrange
    var value = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var other = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var sut =
        new SemanticComparer<ComplexMasterObject>(
            new MemberComparer(
                new AnyObjectComparer()),
            new MemberComparer(
                new ChildFirstComparer()),
            new MemberComparer(
                new ChildSecondComparer()));

    // Act
    var actual = sut.Equals(value, other);

    // Assert
    Assert.True(actual);
}

: Likeness<T> Resemblance

[Fact]
public void TestComplexClassEqualityResemblance()
{
    // Arrange
    var value = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var other = new ComplexMasterObject
    {
        Child1 = new ChildFirst
        {
            SomeStringProp1 = "1",
            SomeIntProp1    =  2
        },
        Child2 = new ChildSecond
        {
            SomeStringProp1 = "3",
            SomeIntProp1    =  4
        },
        SimpleProp          = "5"
    };

    var likeness =
        new Likeness<ComplexMasterObject>(
            value,
            new SemanticComparer<ComplexMasterObject>(
                new MemberComparer(
                    new AnyObjectComparer()),
                new MemberComparer(
                    new ChildFirstComparer()),
                new MemberComparer(
                    new ChildSecondComparer())));
    var sut = likeness.ToResemblance();

    // Act
    var actual = sut.Equals(other);

    // Assert
    Assert.True(actual);
}

public sealed class AnyObjectComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        return object.Equals(x, y);
    }

    public int GetHashCode(object obj)
    {
        return obj.GetHashCode();
    }
}

public sealed class ChildFirstComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        var value = x as ChildFirst;
        var other = y as ChildFirst;

        if (value == null || other == null)
            return false;

        return value.SomeIntProp1    == other.SomeIntProp1
            && value.SomeStringProp1 == other.SomeStringProp1;
    }

    public int GetHashCode(object obj)
    {
        return obj.GetHashCode();
    }
}

public sealed class ChildSecondComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        var value = x as ChildSecond;
        var other = y as ChildSecond;

        if (value == null || other == null)
            return false;

        return value.SomeIntProp1    == other.SomeIntProp1
            && value.SomeStringProp1 == other.SomeStringProp1;
    }

    public int GetHashCode(object obj)
    {
        return obj.GetHashCode();
    }
}
+4

Source: https://habr.com/ru/post/1614595/


All Articles