[英]How do I mock a List of custom objects and set it up to return a real instance of an object
I have a list of objects I need to mock:我有一个需要模拟的对象列表:
var myMock = new Mock<IList<IValidatableTable>>();
My intention is to create a real instance of an object that implements IValidatableTable
like so:我的意图是创建一个实现
IValidatableTable
的 object 的真实实例,如下所示:
var validatableTable = new ValidatableTable();
//... code that modifies the object the way I need it...
And set my mock up so that it returns this object as one of the list items .并设置我的模型,使它返回这个 object 作为列表项之一。
I have tried to use SetupGet, Setup, but I can't figure ou what to put into the lambda expression.我曾尝试使用 SetupGet、Setup,但我不知道要在 lambda 表达式中添加什么。 I have also tried to google but there was only one thread that was close to what I am looking for c# How to mock a list of objects and even that didn't help, because my compiler can't resolve Catalogue.
我也试过谷歌,但只有一个线程接近我正在寻找的c# 如何模拟对象列表,甚至没有帮助,因为我的编译器无法解析目录。
Can you help me please?你能帮我吗?
One of the constructor overloads for Mock
accepts an array of arguments to pass to the mocked type's constructor, so if it's possible to use a List<ValidatableTable>
instead of an IList<ValidatableTable>
, you could do this: Mock
的构造函数重载之一接受 arguments 数组以传递给模拟类型的构造函数,因此如果可以使用List<ValidatableTable>
而不是IList<ValidatableTable>
,您可以这样做:
var constructorArgs = new List<ValidatableTable>
{
//Your "real instance"
new ValidatableTable(),
};
var myMock = new Mock<List<ValidatableTable>>(constructorArgs);
But at this point, I'd question the usefulness of mocking a List
at all since there's no "behaviour" that you can really change - all you can do is control the contents and that doesn't feel like something you need a Mock
for.但在这一点上,我会质疑 mocking
List
的用处,因为没有“行为”可以真正改变——你所能做的就是控制内容,这并不像是你需要Mock
的东西.
As long as you don't want to check whether the members of the list (eg Add
, Remove
) are called in a specific way, I'd not create a mock for the list, but create a real list.只要您不想检查列表的成员(例如
Add
、 Remove
)是否以特定方式调用,我就不会为列表创建模拟,而是创建一个真实的列表。 As List<T>
is a basic and very commonly used member of the framework, it is perfectly fine to use in your test directly without mocking it.由于
List<T>
是框架中一个基本且非常常用的成员,因此在没有 mocking 的情况下直接在您的测试中使用是完全可以的。
IList<IValidatableTable> tables = new List<IValidatableTable>();
You can then fill this list either with mocks or real objects as needed for your test;然后,您可以根据测试需要使用模拟或真实对象填充此列表; if you want to check whether the code uses the list and calls the methods on
IValidatableTable
, you can use mocks:如果要检查代码是否使用列表并调用
IValidatableTable
上的方法,可以使用模拟:
var mockTbl = new Mock<IValidatableTable>();
// Add setups as needed
If - as you write - you want to add a real ValidatableTable
, you can create and add it to your list:如果 - 在你写的时候 - 你想添加一个真正的
ValidatableTable
,你可以创建并将它添加到你的列表中:
tables.Add(new ValidatableTable());
As mocking a list is a tedious process if you look at the number of members and their character (eg enumerator support and so on), you can also check the list after you have run your test whether the items have been changed in the way you expect, eg:由于 mocking 如果您查看成员的数量及其角色(例如枚举器支持等),列表是一个繁琐的过程,您还可以在运行测试后检查列表是否已按照您的方式更改项目期望,例如:
Look at it from a test perspective: is it important to you that items are added using Add
or is it ok if the code is later changed to use AddRange
to add items more efficiently?从测试的角度来看:使用
Add
项目对您来说是否重要,或者如果稍后将代码更改为使用AddRange
更有效地添加项目,是否可以?
When checking the list after the code under test has been run, you find out relevant changes (and the test will only fail if the result does not match your expectations).在运行被测代码后检查列表时,您会发现相关的更改(只有当结果不符合您的期望时测试才会失败)。 In contrast, if you mock the list, you "micro-test" the way, how the list has been used in the code.
相反,如果你模拟列表,你“微测试”的方式,列表是如何在代码中使用的。 It will fail when a list-method has been called in an unexpected way.
当以意想不到的方式调用列表方法时,它将失败。 IMO this will lead to irrelevant test failures.
IMO 这将导致不相关的测试失败。 Hence, I'd prefer to not mock the list in the majority of the cases.
因此,在大多数情况下,我宁愿不要模拟列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.