Skip to content

Instantly share code, notes, and snippets.

@moodmosaic
Last active December 15, 2015 07:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moodmosaic/5225340 to your computer and use it in GitHub Desktop.
Save moodmosaic/5225340 to your computer and use it in GitHub Desktop.
A discussion branch for a question about Likeness on Stack Overflow.
// http://stackoverflow.com/questions/15558873/trouble-using-autofixtures-createproxy-to-use-likeness-semanticcomparison-feat
[Fact]
public void Equality_Behaves_As_Expected()
{
var template = new Fixture().Create<Band>();
var createdBand = new Band
{
Brass = template.Brass,
Strings = template.Brass
};
var likeness = createdBand.AsSource().OfLikeness<Band>()
.Without(x => x.Brass).CreateProxy();
likeness.Strings = createdBand.Strings;
likeness.Should().Be(createdBand); // Passed
likeness.ShouldBeEquivalentTo(createdBand); // Passed
Assert.True(likeness.Equals(createdBand)); // Passed
}
@Lumirris
Copy link

Which assertion checks equality between createdBand (via likeness) and template?

It looks like all it tests is that the Likeness and CreateProxy functionality works, rather than that the SUT (in this case, merely a constructor of Band) is returning the expected output. Consider the case of a BandFactory class, whose CreateBand(string Strings, string Brass) method hides a complex initialization of a Band instance, replacing the simple Band instantiation. How would these assertions verify that the CreateBand() method creates an instance of Band with the same property values as the one created by the fixture, except for the ignored Brass property?

@moodmosaic
Copy link
Author

The createBand and template instances are not affected by the CreateProxy method. Why they should?

With Likeness CreateProxy you basically create a Custom Equality Assertion that allows you to do:

Assert.True(likeness.Equals(createdBand)); // Passed. 

Without it, the original Equality Assertion would fail:

Assert.True(template.Equals(createdBand)); // Failed.

However, the following will also fail:

Assert.True(likeness.Equals(template));

It fails because the Strings value is the one from the createdBand instance.

This behavior is expected, and you can verify it using Likeness directly:

 createdBand.AsSource().OfLikeness<Band>()
     .Without(x => x.Brass).ShouldEqual(template);

Output:

 The provided value `Band` did not match the expected value `Band`. The following members did not match:
      - Strings.

@Lumirris
Copy link

I just now noticed that, in the Band instantiation, the template.Brass value is used to assign to both the Brass and the Strings property. That wasn't my intention. If template.Strings is assigned to the new Band instance's String property instead, the following test then passes, since the only property included in the custom equality assertion is the same in both the new Band instance and the template instance:

Assert.True(likeness.Equals(template));

Perhaps I can clarify the intention of my test by supplying a more descriptive test name:

[Fact]
public void A_Newly_Instantiated_Band_Equals_The_Instance_Created_By_AutoFixture_In_All_Aspects_Except_For_Brass_Property {...}

In your test, I wouldn't expect the createdBand or the template instances to be affected by the CreateProxy() method, it's just that none of your assertions seem to verify what it is that I'm trying to test. Perhaps the fact that the example is so simple is obscuring the need for the test. But imagine the BandFactory.CreateBand(template.Strings, template.Brass), and the Strings and Brass properties were not of type string, but something complex. I might want a test that verifies the BandFactory.CreateBand() method returns an instance equal to (except for the Brass property) an instance whose propertied were passed in as arguments to the method under test.

Does that make my intention more clear?

@moodmosaic
Copy link
Author

Yes :) I think I am trying to understand what you are trying to accomplish.

As always though, it is a lot easier to describe things in code :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment