如何在 C# 中断言结构对象等价(具有严格的类型等价)
How to assert structural object equivalence in C# (with strict type equality)
如何在两个 .NET 对象之间优雅地断言以下类型的等价性(最好使用 Fluent Assertions 库)?
两个对象结构等价如果:
- 两个对象属于相同的(运行 次)类型,并且
- 两个对象的 public 属性(递归地)结构等价。
请注意 subject.Should().BeEquivalentTo(expectation)
不起作用,因为 BeEquivalentTo
不检查类型相等性。例如,如果我们有两个 类 A
和 B
,每个对象都有一个 属性 object X { get; set; }
,那么这两个对象
new A { X = new B { X = new A() }}
和
new B { X = new A { X = new B() }}
将被 BeEquivalentTo
视为等价,即使它们的类型及其属性和子属性的类型不匹配,因此在结构上不符合上述定义。
我想到了这个解决方案,但我希望有一个更优雅的解决方案。
定义自定义 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()));
subject.Should().BeOfType(expectation.GetType).And.Should().BeEquivalentTo(expectation);
如何在两个 .NET 对象之间优雅地断言以下类型的等价性(最好使用 Fluent Assertions 库)?
两个对象结构等价如果:
- 两个对象属于相同的(运行 次)类型,并且
- 两个对象的 public 属性(递归地)结构等价。
请注意 subject.Should().BeEquivalentTo(expectation)
不起作用,因为 BeEquivalentTo
不检查类型相等性。例如,如果我们有两个 类 A
和 B
,每个对象都有一个 属性 object X { get; set; }
,那么这两个对象
new A { X = new B { X = new A() }}
和
new B { X = new A { X = new B() }}
将被 BeEquivalentTo
视为等价,即使它们的类型及其属性和子属性的类型不匹配,因此在结构上不符合上述定义。
我想到了这个解决方案,但我希望有一个更优雅的解决方案。
定义自定义 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()));
subject.Should().BeOfType(expectation.GetType).And.Should().BeEquivalentTo(expectation);