使用起订量,如何验证对象的所有属性均已复制?
我有一个带有 CopyFrom() 方法的接口,该方法从另一个对象复制所有属性。我有一个执行多次VerifyGet() 调用的测试,以确保从传递的对象中检索每个属性,例如:
Thing target = new Thing();
IThing source = new Mock<IThing>();
target.CopyFrom(source.Object);
source.VerifyGet(t => t.Foo);
source.VerifyGet(t => t.Bar);
我想要一种方法来迭代 IThing
的属性,并验证每个属性是自动复制的,因此如果有人添加属性但忘记复制它,测试将会失败。有没有办法通过最小起订量做到这一点?我试过;
foreach (var prop in typeof(IThing).GetProperties())
{
source.VerifyGet(t => prop.Invoke(t, null));
}
但它不起作用,因为 lambda 不代表属性访问器。我认为应该有一种方法可以通过 Expression
类创建一些东西,但我对 LINQ 不够熟悉,无法弄清楚其中应该有什么。
I have an interface with a CopyFrom() method that copies all properties from another object. I have a test that performs several VerifyGet() calls to ensure that each property was retrieved from the passed object, e.g.:
Thing target = new Thing();
IThing source = new Mock<IThing>();
target.CopyFrom(source.Object);
source.VerifyGet(t => t.Foo);
source.VerifyGet(t => t.Bar);
I'd like a way to iterate over the properties of IThing
though and verify that each was copied automatically so the test will fail if someone adds a property but forgets to copy it. Is there a way to do this via Moq? I tried;
foreach (var prop in typeof(IThing).GetProperties())
{
source.VerifyGet(t => prop.Invoke(t, null));
}
but it didn't work since the lambda did not represent a property accessor. I think there should be a way to create something via the Expression
class, but I am not familiar enough with LINQ to figure out what should be in there.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为 Moq 不可能做到这一点,但首先你需要质疑你的测试是否相关。您真正想在这里测试什么?
CopyFrom 方法读取任何属性是否重要?它绝对可以读取所有属性,而不将它们写入新实例,因此这种基于交互的测试并不能真正证明任何事情。
我猜您真正想测试的是目标的属性是否等于源的属性?
假设 IThing 上的属性是可写的,您可以使用 SetupAllProperties 方法创建一个包含所有属性设置的存根:
然后,您需要将目标与源进行比较,以查看所有属性是否匹配。您可以通过在包装真实目标的类中实现特定于测试的 Equals 方法来做到这一点。
如果您认为这工作量太大,您可能需要查看 AutoFixture 的 Likeness 类,它为您提供了通用测试特定的相等比较。这将允许您继续这样的测试:
Likeness 使用 Reflection 来简单地循环包装对象中的所有公共属性,并查看比较对象是否具有相同的这些属性值。
I don't think such a thing is possible with Moq, but first of all you need to question whether your test is relevant. What do you really wish to test here?
Is it important that the CopyFrom method reads any properties? It could definitely read all the properties without writing to them to the new instance, so such an Interaction-based test doesn't really prove anything.
I'm guessing that what you would really like to test is that the properties of the target are equal to the properties of the source?
Assuming that the properties on IThing are writable, you could create a Stub with all the properties set using the SetupAllProperties method:
You would then need to compare the target to the source to see if all properties match. You could do that by implementing a Test-Specific Equals method in a class that wraps the real target.
If you think that is too much work, you may want to check out AutoFixture's Likeness class that gives you a general-purpose Test-Specific equality comparison. That would allow you to continue the test like this:
Likeness uses Reflection to simply loop over all the public properties in the wrapped object and see if the compared object has the same values for those properties.
您可以添加上面的扩展方法,这样您就可以调用:
You can add the above extension method so you can just call: