【问题标题】:How to assert structural object equivalence in C# (with strict type equality)如何在 C# 中断言结构对象等价(严格类型相等)
【发布时间】:2019-03-28 02:58:25
【问题描述】:

如何优雅地断言两个 .NET 对象之间的以下等价性(最好使用 Fluent Assertions 库)?

两个对象结构上等价如果:

  • 两个对象都是相同的(运行时)类型,并且
  • 两个对象的公共属性是(递归的)结构上等价的

请注意,subject.Should().BeEquivalentTo(expectation) 不起作用,因为 BeEquivalentTo 不检查类型相等性。例如,如果我们有两个类AB,每个类都有一个属性object X { get; set; },那么这两个对象

new A { X = new B { X = new A() }}

new B { X = new A { X = new B() }}

将被BeEquivalentTo 视为等效,即使它们的类型及其属性和子属性的类型不匹配,因此在上述定义中不具有结构等效性。

【问题讨论】:

    标签: c# unit-testing fluent-assertions


    【解决方案1】:

    我想出了这个解决方案,但我希望有一个更优雅的解决方案。

    定义一个自定义IEquivalencyStep

        public class StrictTypeEquivalence : IEquivalencyStep
        {          
            public bool CanHandle(IEquivalencyValidationContext context, IEquivalencyAssertionOptions config)
            {
                return context.Subject != null && context.Expectation != null &&
                       context.Subject.GetType() != context.Expectation.GetType();
            }
    
            public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator parent, IEquivalencyAssertionOptions config)
            {
                throw new AssertionFailedException($"{context.SelectedMemberPath}: Expected type {context.Expectation.GetType()} but found {context.Subject.GetType()} instead.");
            }
        }
    

    然后像这样检查等价性:

    subject.Should().BeEquivalentTo(expectation, options => options.Using(new StrictTypeEquivalence()));
    

    【讨论】:

      【解决方案2】:

      subject.Should().BeOfType(expectation.GetType).And.Should().BeEquivalentTo(expectation);

      【讨论】:

      • 这不检查属性的类型相等性(以及属性的属性等),这是问题中所述的结构等价的递归定义所要求的。
      猜你喜欢
      • 2019-05-19
      • 1970-01-01
      • 2022-05-01
      • 2022-04-20
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      相关资源
      最近更新 更多