最近,我一直在阅读很多关于合同和协作测试的文章(主要来自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
我希望我足够清楚,如果没有,我会尽力使这更透明。谢谢大家。
答案 0 :(得分:0)
Stubs和Mocks之间有明显的分离。
存根是一种替代,不能改变测试的结果。例如,传递给主题的输入参数。
另一方面,模拟可能无法通过测试。它是测试对象之间协作的基础。如果未达到预期的协作,则测试将失败。
因此,在您的问题的上下文中,系统的间接输入应该是存根。
答案 1 :(得分:0)
JB Rainsberger有一篇文章似乎正好回答了你的问题:Who Tests The Contract Tests ?
所以这是我的问题:伪造合作者时是否正确? 它应该使用,为被测系统提供间接输入 存根是为了防止未被注意的接口/合同变化?
使用存根而不是什么?
嘲笑?正如@bryanbcook所指出的那样,这并没有产生很大的影响,无论如何,存根更适合这种情况。手动假类甚至没有与协作者实现相同的基类?肯定。
IMO有两种合同变更:
“硬”更改,即协作者方法的返回类型或参数类型的更改。这些修改很容易 - 它们不会被忽视,因为您的测试甚至不能再编译,如果您的虚假协作者实现与真正的协作者相同的接口/基类。
< / LI>“软”更改,即协作者返回给定值或其他值的条件的变化,协作者可以返回或接受的值范围的变化,可抛出的异常等。这些更难以发现,但根据上述文章,可以通过强制执行合同测试和协作测试之间的严格对应来避免它们。