如何比较具有相同名称但不同类型的属性的对象?
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:来自subject的预期成员Id是System.Guid,但找到了System.String。
有什么想法吗?
答案 0 :(得分:3)
以下两种方法可以将对象与具有相同名称的不同类型成员进行比较。
第一种方法是在名为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。