From 4a2c2acda297a815498766af4addec4104799cbf Mon Sep 17 00:00:00 2001 From: stakx Date: Tue, 6 Jun 2017 00:44:49 +0200 Subject: [PATCH] Test ExpressionKey.Equals against bad hashcodes Issue 328 revealed that ExpressionKey did not perform equality check- ing correctly for objects with the same hash code. This commit adds tests for that specific scenario. --- UnitTests/Regressions/IssueReportsFixture.cs | 87 ++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/UnitTests/Regressions/IssueReportsFixture.cs b/UnitTests/Regressions/IssueReportsFixture.cs index 6d062bbbb..9bd2961e1 100644 --- a/UnitTests/Regressions/IssueReportsFixture.cs +++ b/UnitTests/Regressions/IssueReportsFixture.cs @@ -391,6 +391,93 @@ public void strict_mock_differenciates_multiple_setups_with_same_arguments_in_di #endregion // #135 + #region 328 + + public class Issue328 + { + public struct BadlyHashed : IEquatable> + { + public static implicit operator BadlyHashed(T value) + { + return new BadlyHashed(value); + } + + private T value; + + public BadlyHashed(T value) + { + this.value = value; + } + + public bool Equals(BadlyHashed other) + { + return this.value.Equals(other.value); + } + + public override bool Equals(object obj) + { + return obj is BadlyHashed other && this.Equals(other); + } + + public override int GetHashCode() + { + // This is legal: Equal objects must have equal hashcodes, + // but objects with equal hashcodes are not necessarily equal. + // We are essentially rendering GetHashCode useless for equality + // comparison, so whoever compares instances of this type will + // (or should!) end up using the more precise Equals. + return 0; + } + } + + [Fact] + public void Two_BadlyHashed_instances_with_equal_values_are_equal() + { + BadlyHashed a1 = "a", a2 = "a"; + Assert.Equal(a1, a2); + Assert.Equal(a2, a1); + } + + [Fact] + public void Two_BadlyHashed_instances_with_nonequal_values_are_not_equal() + { + BadlyHashed a = "a", b = "b"; + Assert.NotEqual(a, b); + Assert.NotEqual(b, a); + } + + public interface IMockableService + { + void Use(BadlyHashed wrappedString); + } + + [Fact] + public void Strict_mock_expecting_calls_with_nonequal_BadlyHashed_values_should_verify_when_called_properly() + { + // The above test has already established that `a` and `b` are not equal. + BadlyHashed a = "a", b = "b"; + + // We are setting up two calls in Strict mode, i.e. both calls must happen. + var mock = new Mock(MockBehavior.Strict); + { + mock.Setup(service => service.Use(a)); + mock.Setup(service => service.Use(b)); + } + + // And they do happen! + { + var service = mock.Object; + service.Use(a); + service.Use(b); + } + + // So the following verification should succeed. + mock.VerifyAll(); + } + } + + #endregion // #328 + // Old @ Google Code #region #47