【问题标题】:Compare 2 not identical DTO but have common properties in Fluent Assertion比较 2 个不同的 DTO,但在 Fluent Assertion 中有共同的属性
【发布时间】:2022-01-14 13:37:24
【问题描述】:

我正在为手动映射器编写单元测试。它将一个对象映射到两个不同的类,但具有共同的属性。 fluent assertion中如何比较它们的属性是否相等?

这是我尝试过的

 var domain = new Domain.ConsentDefinition()
{
     SomeProperty = 1,
     ListOfFirstDTO = new List<FirstDTO>()
     {
          new FirstDTO()
          {
             Name = "Label",
             Age = 18,
          }
     },
     SomeOtherProperty = "one"
}

ef = domain.ToEF();

domain.SomeProperty.Should().Be(ef.SomeProperty);
domain.SomeOtherProperty.Should().Be(ef.SomeOtherProperty);
domain.ListFirstDTO.Should().Equal(ef.ListOfSecondDTO); // This is NOT working

public class FirstDTO
{
   public string Name {get;set;}
   public int Age {get;set;}
}

public class SecondDTO
{
   public string Name {get;set;}
   public int Age {get;set;}
   public string Email {get;set;}
}

【问题讨论】:

    标签: c# fluent-assertions


    【解决方案1】:

    覆盖 firstDTO 的等于,以便您比较值而不是引用:

    
            public override bool Equals(object obj)
            {
                if (obj == null || !(obj is FirstDTO) || !(obj is SecondDTO))
                {
                    return false;
                }
                
                if(obj is SecondDTO){
                  return (this.Name == ((SecondDTO)obj).Name)
                    && (this.Age == ((SecondDTO)obj).Age)
    
                }
                // if obj is instance of FirstDTO check the rest of fields...
            }
    
    

    然后再次运行

     domain.ListFirstDTO.Should().Equal(ef.ListOfSecondDTO); // This is NOT working
    
    

    另一个不需要覆盖 equals 的更优雅的解决方案是

    
    domain.ListFirstDTO.Select(c => c.Name).Should().Equal(ef.ListOfSecondDTO.Select(c => c.Name);
    
    domain.ListFirstDTO.Select(c => c.Age).Should().Equal(ef.ListOfSecondDTO.Select(c => c.Age);
    

    fluentassertion/collections

    【讨论】:

    • 我只是注意到它使用了'equal' 有没有办法像其他人一样使用'be'?
    • 我不太确定。我认为“Be”适用于单一属性,不适用于 Collections。你仍然可以用“Be”做的是同时遍历两个列表并比较给定索引的值
    • 而不是Equal 使用Should().BeEquivalentTo(ef.ListOfSecondDTO) - 你不需要重写Equals 方法。寻找丹尼斯的答案
    【解决方案2】:
    domain.Should().BeEquivalentTo(new
    {
       SomeProperty = ef.SomeProperty,
       SomeOtherProperty = ef.SomeOtherProperty,
       ListFirstDTO = ef.ListOfSecondDTO
    });
    

    domain.Should().BeEquivalentTo(ef, options => options
      .Including(x => x.SomeProperty)
      .Including(x => x.SomeOtherProperty)
      .Including(x => x.ListOfSecondDTO));
    

    默认情况下,FA 将通过忽略集合中项目的顺序来比较两个集合。使用WithStrictOrdering 来控制它。

    如果第二个 DTO 实现 Equals,那么 FA 将使用它。您可以使用 ComparingByMembers&lt;T&gt; 选项覆盖它。

    【讨论】:

      猜你喜欢
      • 2021-04-30
      • 1970-01-01
      • 2018-06-05
      • 2015-09-04
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      相关资源
      最近更新 更多