如何比较具有相同名称但不同类型的属性的对象?
public class A
{
public Guid Id { get; set; }
}
public class B
{
public string Id { get; set; }
}
public static B Map(A a){
return new B { Id = a.Id.ToString() };
}
版本1:
void Main()
{
A a = new A { Id = Guid.NewGuid() };
B b = Map(a);
b.Should().BeEquivalentTo(a);
}
这将产生以下错误:
AssertionFailedException:预期成员ID为{ff73e7c7-21f0-4f45-85fa-f26cd1ecafd0},但发现“ {ff73e7c7-21f0-4f45-85fa-f26cd1ecafd0}”。
该文档建议使用Equivalence Comparison Behavior可以实现自定义属性声明规则
版本2:
void Main()
{
A a = new A { Id = Guid.NewGuid() };
B b = Map(a);
b.Should().BeEquivalentTo(a,
options => options
.Using<Guid>(ctx => ctx.Subject.Should().Be(ctx.Expectation))
.WhenTypeIs<Guid>());
}
但是,如果属性的类型不同,则会产生运行时异常。
AssertionFailedException:期望主题的成员ID为System.Guid,但找到了System.String。
有任何想法吗?
最佳答案
这是比较具有相同名称的不同类型成员的对象的两种方法。
第一种方法是指定名为Id
的成员之间的等效性
A expected = new A { Id = Guid.NewGuid() };
B actual = Map(expected);
actual.Should().BeEquivalentTo(expected,
options => options
.Using<object>(ctx => ctx.Subject.Should().Be(ctx.Expectation.ToString()))
.When(info => info.SelectedMemberPath.EndsWith("Id")));
第二种方法使用https://stackoverflow.com/a/47947052/1087627中的
DifferentObjectsEquivalencyStep
和您自己的Map
函数。然后,它将
A
的实例转换为B
,现在可以轻松进行比较。AssertionOptions.AssertEquivalencyUsing(c =>
c.Using(new DifferentObjectsEquivalencyStep<A, B>(Map)));
A expected = new A { Id = Guid.NewGuid() };
B actual = Map(expected);
actual.Should().BeEquivalentTo(expected);
关于它有一个开放的issue。