合同测试是否意味着存根?

时间:2012-12-03 21:47:16

标签: unit-testing testing mocking tdd stubs

最近,我一直在阅读很多关于合同和协作测试的文章(主要来自J.B. Rainsberger)。为了搞定它,我开始了一个小项目。

根据我的理解,合同测试的责任是确保实现尊重其接口固有合同。换句话说,它鼓励利斯科夫替代原则。

模拟对象协作者基本上就是对它做出假设。现在,如果这些假设发生变化会发生什么?如果我像这样使用Mockito模仿协作者(这与存根相同):

 when(collaborator.doSomething(someArgument)).thenReturn(someValue);

当我修改协作者界面(即合同)时,我将无法注意到这些变化。

所以这是我的问题:当伪造一个为被测系统提供间接输入的协作者时,应该使用存根来防止未被注意的接口/合同变化吗?

以下是我已经检查过的一些链接:

removing-the-integration-test-scam-understanding-collaboration-and-contract

writing contract tests in java differently

我希望我足够清楚,如果没有,我会尽力使这更透明。谢谢大家。

2 个答案:

答案 0 :(得分:0)

Stubs和Mocks之间有明显的分离。

存根是一种替代,不能改变测试的结果。例如,传递给主题的输入参数。

另一方面,模拟可能无法通过测试。它是测试对象之间协作的基础。如果未达到预期的协作,则测试将失败。

因此,在您的问题的上下文中,系统的间接输入应该是存根。

答案 1 :(得分:0)

JB Rainsberger有一篇文章似乎正好回答了你的问题:Who Tests The Contract Tests ?

  

所以这是我的问题:伪造合作者时是否正确?   它应该使用,为被测系统提供间接输入   存根是为了防止未被注意的接口/合同变化?

使用存根而不是什么?

嘲笑?正如@bryanbcook所指出的那样,这并没有产生很大的影响,无论如何,存根更适合这种情况。

手动假类甚至没有与协作者实现相同的基类?肯定。

IMO有两种合同变更:

  • “硬”更改,即协作者方法的返回类型或参数类型的更改。这些修改很容易 - 它们不会被忽视,因为您的测试甚至不能再编译,如果您的虚假协作者实现与真正的协作者相同的接口/基类。

    < / LI>
  • “软”更改,即协作者返回给定值或其他值的条件的变化,协作者可以返回或接受的值范围的变化,可抛出的异常等。这些更难以发现,但根据上述文章,可以通过强制执行合同测试和协作测试之间的严格对应来避免它们。