Why doesn't simple test pass using AutoFixture Freeze, SemanticComparison Likeness and CreateProxy?

StackOverflow https://stackoverflow.com/questions/15470997

  •  24-03-2022
  •  | 
  •  

Question

I'm trying to understand how to use the CreateProxy() feature of Likeness<T>() using two instances of a simple class.

public class Band
{
    public string Strings { get; set; }
    public string Brass { get; set; }
}

With the following test, I use a Fixture to Create<T> a Band instance with values for the two string properties.

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange
    var fixture = new Fixture();
    fixture.Customize(new AutoMoqCustomization());

    var original = fixture.Create<Band>();
    //   Brass something like --> "Brass65756b89-d9f3-42f8-88fc-ab6de5ae65cd"
    //   Strings something like --> "Strings7439fa1b-014d-4544-8428-baea66858940"

    // act
    var dupe = new Band {Brass = original.Brass, 
                         Strings = original.Strings};
    //   Brass same as original's like --> "Brass65756b89-d9f3-42f8-88fc-ab6de5ae65cd"
    //   Strings same as original's like --> "Strings7439fa1b-014d-4544-8428-baea66858940"

I've tried many different assertions, but the crux of the matter seems to be that the CreateProxy method is not populating the properties of Band, so that even when I try to compare two instances of Band with the same property values, the instance from the CreateProxy method always has null values.

    // assert
    var likeness = dupe.AsSource().OfLikeness<Band>()
                       .Without(x => x.Brass).CreateProxy();
    //   Brass & String properties are null using dupe as source of likeness (!)

    //var likeness = original.AsSource().OfLikeness<Band>()
    //                       .Without(x => x.Brass).CreateProxy();
    //   Brass & String properties are null using original as source of likeness (!)

    //Assert.True(likeness.Equals(original)); // Fails
    //Assert.True(original.Equals(likeness)); // Fails

    // below are using FluentAssertions assembly
    //likeness.Should().Be(original);           // Fails (null properties)
    //original.Should().Be(likeness);           // Fails (null properties)
    //likeness.ShouldBeEquivalentTo(original);  // Fails (null properties)
    //original.ShouldBeEquivalentTo(likeness);  // Fails (null properties)
}

I've gotta be doing something wrong, but I've read everything I can find on the Ploeh blog and SO, and can't find an example suitably simple enough to compare to what I'm doing. Any ideas?

Was it helpful?

Solution

If you assign the values on the proxied instance (after calling the CreateProxy method) the test passes:

[Fact]
public void Equality_Behaves_As_Expected()
{
    // AutoMoqCustomization is not necessary.
    var original = new Fixture().Create<Band>();

    var likeness = original
        .AsSource()
        .OfLikeness<Band>()
        .Without(x => x.Brass)
        .CreateProxy();

    likeness.Brass = "foo"; // Ignored.
    likeness.Strings = original.Strings;

    Assert.True(likeness.Equals(original));
    likeness.Should().Be(original);
    likeness.ShouldBeEquivalentTo(original);
}

Keep in mind that Likeness creates a proxy on the target type and only that type's instance overrides Equals.

Since the source type remains intact, the following assertions will not succeed:

Assert.True(original.Equals(likeness));
original.Should().Be(likeness);
original.ShouldBeEquivalentTo(likeness);

Update

From version 3.0.4 and above the values are automatically copied to the proxy instance (which means, likeness.Strings = original.Strings; is going to happen automatically).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top