单元测试 – 如何为主要面向服务的应用程序编写有用的单元测试?

我已成功使用单元测试一段时间了,但我开始认为它们只适用于实际执行大量逻辑的类/方法 – 解析器,数学运算,复杂的业务逻辑 – 所有测试的良好候选者, 没有问题.我真的很难弄清楚如何使用另一类对象的测试:那些主要通过委托操作的对象.

例证:我当前的项目协调了很多数据库和服务.大多数类只是服务方法的集合,大多数方法执行一些基本的条件逻辑,可能是for-each循环,然后调用其他服务.

对于像这样的对象,模拟实际上是唯一可行的测试策略,所以我尽职尽责地为其中的几个设计了模拟.我真的,真的不喜欢它,原因如下:

>使用模拟来指定对行为的期望会在我改变类实现时使事情中断,即使这不是那种应该对单元测试产生影响的变化.在我看来,单元测试应该测试功能,而不是指定“方法需要做A,然后是B,然后是C,而不是按顺序.”我喜欢测试,因为我可以自信地改变事物,我知道如果有什么事情发生了 – 但是嘲讽只会让屁股变得更加痛苦.
>如果预期的行为很简单,编写模拟通常比编写类本身更有用.
>因为我在测试中使用了完全不同的所有服务和组件对象的实现,最后,我所有的测试都真正验证了行为的最基本框架:“if”和“for”语句仍然有效.无聊.我并不担心这些.

我的应用程序的核心是所有部分如何协同工作,所以我正在考虑
开沟单元完全测试(除了他们显然合适的地方)并转而进行外部集成测试 – 更难设置,覆盖更少的可能情况,但实际上运行系统,因为它意味着运行.

我没有看到任何使用模拟实际上有用的情况.

思考?

最佳答案
如果你可以编写快速可靠的集成测试,那么我会说它去吧.
仅在必要时使用模拟和/或存根来保持测试.

但请注意,使用模拟并不一定像您所描述的那样痛苦:

>模拟API允许您使用松散/非严格模拟,这将允许从被测单元到其协作者的所有调用.因此,您不需要记录所有调用,只需要记录需要为测试生成一些所需结果的调用,例如方法调用的特定返回值.
>使用一个好的模拟API,你将不得不编写一些测试代码来指定模拟.在某些情况下,您可能会使用单个字段声明或应用于测试类的单个注释.
>您可以使用部分模拟,以便实际上只为给定测试模拟服务/组件类的必要方法.这可以在不指定字符串中的所述方法的情况下完成.

转载注明原文:单元测试 – 如何为主要面向服务的应用程序编写有用的单元测试? - 代码日志