Могут ли FluentAssertions ShouldBeEquivalent работать с типами записей c # 9?

#c# #unit-testing #datetime #fluent-assertions

#c# #модульное тестирование #дата и время #fluent-утверждения

Вопрос:

Я возился с некоторыми новыми функциями c # 9, и я столкнулся с чем-то, что не очень весело. Если я попытаюсь использовать Should().BeEquivalentTo() для записи с DateTimeOffset , установив параметр Using для DateTimeOffset для использования BeCloseTo , тест завершится неудачей, даже если DateTimeOffset находится в пределах допустимой точности. Есть ли способ заставить это работать (без изменения записи на класс lol)? Большое спасибо!

Пример:

    public class ExampleTest
   {

      [Fact]
      public void FunWithRecords()
      {
         var thing1 = new Thing
         {
            SomeDate = DateTimeOffset.UtcNow
         };
         var thing2 = new Thing
         {
            SomeDate = DateTimeOffset.UtcNow.AddSeconds(2)
         };
         thing1.Should().BeEquivalentTo(thing2, o =>
            o.Using<DateTimeOffset>(ctx =>
               ctx.Subject.Should().BeCloseTo(ctx.Expectation, 10000))
               .WhenTypeIs<DateTimeOffset>());
      }
   }
   
   public record Thing
   {
      public DateTimeOffset SomeDate {get; init;}
   }
  

Ответ №1:

И я ответил на свой собственный вопрос. Это делает то, что:

 thing1.Should().BeEquivalentTo(thing2, o => o
         .ComparingByMembers<Thing>()
         .Using<DateTimeOffset>(ctx => 
               ctx.Subject.Should().BeCloseTo(ctx.Expectation, 10000)).WhenTypeIs<DateTimeOffset>());
  

Ответ №2:

Fluent Assertions поддерживает записи. Это «просто» обычные классы с генерируемыми компилятором

  • Методы сравнения равенства на основе значений
  • Переопределение для GetHashCode()
  • Копирование и клонирование элементов
  • PrintMembers и toString()

https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9#record-types

По умолчанию BeEquivalentTo используется object.Equals переопределение if для ожидаемого типа для сравнения экземпляров. При переключении с простого класса на запись тип теперь переопределяется object.Equals , что изменяет способ сравнения экземпляров. Чтобы переопределить это поведение по умолчанию, вы можете использовать ComparingByMembers<T> .

https://fluentassertions.com/objectgraphs/#value-types