什么时候应该使用模拟对象?


14

我已经阅读了很多有关TDD的内容,但是我仍然有疑问。例如,我有以下类图:

在此处输入图片说明

这是一个简单的示例,仅用于了解TDD和模拟对象。

我应该先写哪个测试?产品,然后,最后,订购?如果这样做,我应该使用生产线产品来测试订单还是应该使用模拟对象?我什么时候应该使用模拟对象?我应该在XP和TDD中使用UML吗?

我还没有这些东西。

Answers:


10

从图中判断,Product是一个哑数据类,没有测试功能。因此,我将开始为Line编写测试(并实现TDD样式),然后再按Order编写测试,并进行相关性测试。通常,在开始对更高级别的课程进行工作之前,先对较低级别的课程进行测试是明智的(即,取决于较低级别的课程)。这样可以更有效地捕获错误。

是否需要使用模拟对象取决于测试类的实际依赖关系。如果这些是简单的类,您可以轻松地实例化和设置测试所需的任何所需数据/状态,则无需模拟。(这里的示例设计似乎是这种情况。)但是,如果任何依赖项都难以初始化/自身具有广泛的依赖项/具有不良的副作用/依赖于外部资源(例如DB),那么就有意义改为使用模拟对象。


正如我之前所说,这是一个简单的场景,只是学习TDD和Mock对象...一个很好的答案,谢谢。那么UML呢?我应该避免吗?

@thomas,无需避免UML,它与TDD不冲突。UML非常适合可视化/交流设计问题。在某些开发阶段这可能非常有用。但是,设计在不断发展,试图使美观,详细的UML系统图与代码保持同步可能很快成为一种负担。所以,要记得把它扔掉,当你不需要它了:-)
彼得Török

1
@thomas,顺便说一句这里的惯例是给予好评的回答对您有帮助,通过点击向上箭头旁边的答案:-)
彼得Török

4

我在这里看不到模拟对象的太多需求。正如其他人指出的那样,如果依赖关系难以建立,则最需要这些。

例如,当我们测试控制器时,我们将它们与Ruby on Rails项目一起使用,并且需要用户登录,这需要调用另一个控制器并将其部分信息存储在cookie中。在这种情况下,当被询问某些访问权限时,模拟返回true的登录用户会很有帮助。


2

通常,对于测试,您希望隔离被测试的系统/对象,因此您将模拟其中的任何内容。因此,使用类图,在测试订单对象时,请将模拟对象用作线对象。测试Line时,对Order和Product使用模拟。测试产品时,将模拟用于Line。


由于Product不依赖Line,因此无需(也无需)在其中对Line使用模拟。行和顺序相同。
彼得Török

2

“ TDD主要是一种设计技术,其副作用是确保对源代码进行全面的单元测试” – Scott W. Ambler

这个想法是通过编写单元测试来找到设计。就您而言,似乎您已经拥有了设计,这有点违背了TDD的目的(假设您的设计是最终的)。

关于嘲笑。如果要模拟,建议您在编写Line的测试时模拟Product,在测试Order时模拟Line。但这在这里可能会过分杀伤力。我个人尝试尽可能地限制模拟,并使用它来解耦对外部类(例如数据库实例)的依赖。


2
我只是有一个简单的类图...

-1因此,对设计的思考(包括在类图中进行草绘)会阻止您进行TDD?这听起来完全是错误的。
Bjarke Freund-Hansen

1
@bjarkef:请再次阅读我的答案。如果设计是最终的,则不能真正使用TDD来驱逐设计,这就是TDD的目的。而且我认为这也是使OP感到困惑的原因:他已经有了解决方案,现在正尝试为其编写测试。“我应该先写哪个测试,产品还是订单”。如果您首先编写测试,那么这个问题并不重要。
Martin Wickman

您如何确定没有任何测试或生产代码的最终设计?假设您要创建可行的东西。
JeffO 2011年

@Jeff:显然不能。这是TDD可以帮助您的一件事。
Martin Wickman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.