Skip to content

Regression in Is.EqualTo(DateTime) constraint in 4.3.x for types that implement IEquatable<DateTime> #4954

Description

@KrzysFR

After upgrading from 4.2.2 to 4.3.2, I have a few regressions in tests that compare a type that implements IEquatable<DateTime> with an Is.EqualTime(DateTime) constraint which fails, and the EqualTo(DateTime) method is not called on the instance.

It seems to be due to #4882 (#4877) which adds a custom constraint implementation EqualTimeBaseConstraint<T>, which only tests if actual is a T (DateTime or DateTimeOffset in this case), but does not test if TActual implements IEquatable<DateTime> or IEquatable<DateTimeOffset> and returns false. Looking at other custom constraints, for example EqualsStringWithoutUsingConstraints, it tests for IEqualtable<string> as well.

Here is a small repro. The test passes in 4.2.2, but fails in 4.3.2. Neither Equals(object) nor Equals(DateTime) are called on DateTimeLike in 4.3.2.

public sealed class DateTimeLike : IEquatable<DateTime>
{

	public DateTime Value { get; init; }

	public bool Equals(DateTime other) => other.Equals(this.Value);

	public override bool Equals(object? obj) => obj is DateTime dt && Equals(dt);

	public override int GetHashCode() => this.Value.GetHashCode();

	public override string ToString() => this.Value.ToString(CultureInfo.InvariantCulture);

}

[TestFixture]
public class DateTimeEqualityFacts
{

	[Test]
	public void Test_IEquatableOfDateTime_Is_EqualTo()
	{
		var now = DateTime.Now;
		var item = new DateTimeLike { Value = now };

		Assert.That(item, Is.EqualTo(now));
		// 4.2.2: PASS
		// 4.3.2: FAIL
	}

}

Result:

  Failed: Assert.That(item, Is.EqualTo(now))
  Expected: 2025-03-07 11:37:37.0200461
  But was:  <03/07/2025 11:37:37>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions