如何避免从模拟对象列表返回模拟 [英] how to avoid returning mocks from a mocked object list

查看:70
本文介绍了如何避免从模拟对象列表返回模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试模拟/责任驱动的设计.对于需要服务来检索其他对象的对象,我似乎有一些问题要避免从模拟中返回模拟.

I'm trying out mock/responsibility driven design. I seem to have problems to avoid returning mocks from mocks in the case of objects that need a service to retrieve other objects.

一个示例可以是一个对象,该对象检查是否已支付上个月的账单.它需要一种检索账单清单的服务.因此,我需要在测试中模拟该billRetrievalService.同时,我需要BillRetrievalMock返回模拟的Bills(因为我不希望我的测试依赖Bill实施的正确性).

An example could be an object that checks whether the bills from last month are paid. It needs a service that retrieves a list of bills. So I need to mock that billRetrievalService in my tests. At the same time I need that BillRetrievalMock to return mocked Bills (since I don't want my test to rely on the correctness of the Bill implementation).

我的设计有缺陷吗?有更好的方法来测试吗?还是使用查找器对象(在这种情况下是查找钞票)时需要的方式?

Is my design flawed? Is there a better way to test this? Or is this the way it will need to be when using finder objects (the finding of the bills in this case)?

旁注:尽管Bill可能是价值对象的候选者,但是当集合中不包含价值对象(例如,用户)时,仍然存在更大的问题.

side note: althout Bill might be a value object candidate, the wider problem still remains when the collections aren't containing value objects (eg Users).

推荐答案

在大多数情况下,如果我需要一个模拟返回另一个模拟,我会发现一个在另一个方向更有意义的依赖项.换句话说,模拟返回模拟通常表示违反了依赖倒置原则.

Most of the time, if I need a mock to return another mock, I find a dependency that makes more sense in the other direction. Stated differently, mock-returning-mock usually points to a violation of the Dependency Inversion Principle.

一个常见的例外:一个创建对象的工厂(而不是每次仅返回相同对象的持有人").如果我在一生中需要创建多个相同类型的对象,则可能需要依赖ObjectFactory并调用#createObject(),然后可能会对这些对象设置期望.即使这样,我也会对此提出质疑.上一级调用堆栈中的其他内容可能可以为我创建Object并根据需要将它们提供给我.

One common exception: a factory that creates objects (as opposed to a "holder" that simply returns the same object each time). If I need to create multiple objects of the same type during my lifetime, then I might need to depend on an ObjectFactory and invoke #createObject(), then perhaps set expectations on the Objects. Even so, I would question this. It might be possible for something else one level up the call stack to create Objects for me and give them to me as needed.

ObjectHolder的情况下,我宁愿直接依赖Object并强迫我的呼叫者按需要将其提供给我,而不是依靠ObjectHolder来获得Object.这尊重了上下文独立性的理想设计属性.

In the ObjectHolder case, rather than depending on the ObjectHolder to get the Object, I prefer to depend on the Object directly and force my caller to give it to me however it wants. This respects the desirable design property of context independence.

此问题的一个特定版本是虚拟时钟"模式.有时您需要依赖虚拟时钟,但通常最好是要求时间戳记(即时请求"模式),或者最坏的情况是要求时间戳记源于何处.测试可以提供方便的,经过硬编码的时间戳的受控流,但是将系统时钟转换为时间戳流也很容易.

One specific version of this issue is the "Virtual Clock" pattern. Sometimes you need to depend on virtual clock, but often it's better simply to demand a timestamp ("Instantaneous Request" pattern) or, at worst, a stream of timestamps, wherever that comes from. Tests could provide a controled stream of convenient, hardcoded timestamps, but it's also easy to turn the system clock into a stream of timestamps.

这篇关于如何避免从模拟对象列表返回模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆