简体   繁体   English

如何模拟自定义对象列表并将其设置为返回 object 的真实实例

[英]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.只要您不想检查列表的成员(例如AddRemove )是否以特定方式调用,我就不会为列表创建模拟,而是创建一个真实的列表。 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());

On mocking the list关于 mocking 的列表

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 如果您查看成员的数量及其角色(例如枚举器支持等),列表是一个繁琐的过程,您还可以在运行测试后检查列表是否已按照您的方式更改项目期望,例如:

  • Does the length meet your expectations?长度符合您的期望吗?
  • Have new items been added with the expected data?是否添加了带有预期数据的新项目?
  • Have items been removed that should have been removed?是否删除了应该删除的项目?

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.

相关问题 Moq可以返回传递给在具有void返回类型的Mock上调用的Setup方法的实际对象实例吗? - Can Moq return the real object instance passed into a Setup method called on a Mock with a void return type? 如何设置 object 的属性并返回字符串列表 - how to set up property of an object and return a string list 我是否需要仅在Mock对象上显式设置期望的返回值? - Do I need to explicitly set expected return values on Mock object only? 如何避免“对象引用未设置为对象的实例”? - How do I avoid 'Object reference not set to an instance of an object'? 如何修复“对象引用未设置为对象的实例”? - How do I fix “Object reference not set to an instance of an object”? 如何解决对象引用未设置为对象的实例 - How Do I Solve Object Reference Not Set To An Instance Of An Object 无论泛型类型如何,我都可以设置一个模拟返回吗? - Can I set-up a mock to return regardless of generic type? 如何将自定义对象列表绑定到ComboBox? - How do I do bind list of custom objects to ComboBox? 如何为应用程序设置单个对象实例? - How to set up a single object instance for an application? 如何在模拟上设置方法以默认返回 null? - How do I set up methods on mocks to return null by default?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM