Skip to content

Instantly share code, notes, and snippets.

@yreynhout
Created May 2, 2014 12:01
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 yreynhout/7c07e87e328ec0c7b08c to your computer and use it in GitHub Desktop.
Save yreynhout/7c07e87e328ec0c7b08c to your computer and use it in GitHub Desktop.
[Test]
public void EqualityMembersOverridden()
{
new EqualityMembersOverriddenAssertion(Func<object> sutFactory).
EqualsCase(object other).
EqualsCase(object other).
NotEqualsCase(object other).
NotEqualsCase(object other).
NotEqualsCase(object other).
Verify();
}
@moodmosaic
Copy link

If the type overrides Equals and GetHashCode correctly, compose an assertion of basic equality rules as below:

public class CompositeEqualityBehaviorTests
{
    [Test]
    public void VerifyCompositeEqualityBehaviorOnValueObject()
    {
        var fixture = new Fixture();
        var assertion =
            new CompositeIdiomaticAssertion(
                new EqualsNullAssertion(fixture),
                new EqualsSelfAssertion(fixture),
                new EqualsNewObjectAssertion(fixture),
                new EqualsSuccessiveAssertion(fixture));
        assertion.Verify(typeof(ValueObject));
    }
}

Assuming that ValueObject is defined as:

public class ValueObject
{
    public readonly int x;
    public readonly int y;

    public ValueObject(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public int X
    {
        get { return x; }
    }

    public int Y
    {
        get { return y; }
    }

    public override bool Equals(object obj)
    {
        var other = obj as ValueObject;
        if (other != null)
            return this.X == other.X
                && this.Y == other.Y;
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return
            this.X.GetHashCode() ^
            this.Y.GetHashCode();
    }
}

@moodmosaic
Copy link

If the type doesn't override Equals and GetHashCode use structural and/or semantic equality:

public class Projection
{
    public string Property { get; set; }
}

public class StructuralEqualityBehaviorTests
{
    [Test, AutoData]
    public void ProjectionsAreDifferentInstances(
        Projection sut,
        Projection other)
    {
        Assert.AreNotSame(sut, other);
    }

    [Test, AutoData]
    public void ProjectionsValuesAreEqual(
        [Frozen]string expected,
        Projection sut,
        Projection other)
    {
        Assert.True(
            expected == sut.Property &&
            expected == other.Property);
    }

    [Test, AutoData]
    public void ProjectionsAreNotEqual(
        [Frozen]string expected,
        Projection sut,
        Projection other)
    {
        Assert.False(sut.Equals(other));
        // Passes although it should fail - 'sut' and 'other' values are equal.
    }

    [Test, AutoData]
    public void ProjectionsAreNotEqualEvenUsingNUnitSpecialSemantics(
        [Frozen]string expected,
        Projection sut,
        Projection other)
    {
        Assert.AreNotEqual(sut, other);
        // Passes although it should fail - 'sut' and 'other' values are equal.
    }

    [Test, AutoData]
    public void ProjectionsAreEqualUsingStructuralEquality(
        [Frozen]string expected,
        Projection sut,
        Projection other)
    {
        sut.AsSource().OfLikeness<Projection>().ShouldEqual(other);
    }
}

@moodmosaic
Copy link

The tests in the 1st comment are using AutoFixture.Idioms.
The tests in the 2nd comment are using SemanticComparison and AutoFixture.NUnit2.

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