koe*_*oen 15 tdd unit-testing mocking
我正在尝试模拟/责任驱动的设计.在需要服务来检索其他对象的对象的情况下,我似乎有问题避免从模拟中返回模拟.
一个例子可以是检查上个月的账单是否已支付的对象.它需要一个检索账单清单的服务.所以我需要在我的测试中模拟billRetrievalService.同时我需要BillRetrievalMock返回模拟的Bills(因为我不希望我的测试依赖于Bill实现的正确性).
我的设计有缺陷吗?有没有更好的方法来测试这个?或者这是使用finder对象时需要的方式(在这种情况下查找账单)?
旁注:尽管Bill可能是一个值对象候选者,但当集合不包含值对象(例如Users)时,更广泛的问题仍然存在.
J. *_*ger 13
大多数时候,如果我需要一个模拟来返回另一个模拟,我发现一个依赖在另一个方向更有意义.换句话说,mock-returning-mock通常指向违反依赖性倒置原则.
一个常见的例外:一个创建对象的工厂(而不是每次只返回同一个对象的"holder").如果我需要在我的生命周期中创建多个相同类型的对象,那么我可能需要依赖ObjectFactory和调用#createObject(),然后可能设置对象的期望.即便如此,我也会质疑这一点.调用堆栈中的其他内容可能有可能为Object我创建s并根据需要将它们提供给我.
在这种ObjectHolder情况下,我宁愿直接依赖并强制我的调用者将它提供给我,而不是依赖于ObjectHolder获取它.这尊重上下文独立性的理想设计属性.ObjectObject
此问题的一个特定版本是"虚拟时钟"模式.有时您需要依赖虚拟时钟,但通常最好只需要时间戳("瞬时请求"模式),或者最坏的情况是需要时间戳流,无论来自哪里.测试可以提供方便,硬编码时间戳的控制流,但也很容易将系统时钟转换为时间戳流.
Esk*_*ola 11
模拟返回模拟是一种强烈的代码气味 - 设计可能存在问题.可能是Bills应该是不可变的值对象,不应该被模拟.或者与类的设计和职责有些混淆.
" 成长对象软件,测试指导和纸模拟角色"这本书,不是来自模拟对象发明者的对象,值得一读.
作为Testuvius建议的方式,绝对不应该采取任何原则,不管多好,因此也应该遵守规则,你不应该需要模拟返回模拟,有些情况下这是非常合适的.
正如Gutzofter建议的那样,你可以将你的对象分成两个,一个用于实际验证,另一个用于检索要验证的账单.这种"仅责任单一"原则应用的优点是验证器更通用且可重复使用.另一方面,如果您只有这个简单的用例并且不需要更高的可重用性,那么将检索和验证保持在单个类中是非常实用的.仅仅为了满足抽象原则而进行的实际需要和实际利益的分层,物体数量的爆炸等不合理是不好的.你总是必须权衡利弊,现实很少是简单和美丽的:-)这种实用方法的很好的例子是亚当比恩的真实世界Java EE模式 - 重新思考最佳实践.
| 归档时间: |
|
| 查看次数: |
2946 次 |
| 最近记录: |