我读过各种关于测试中模仿和存根的文章,包括Martin Fowler的《Mocks Aren't Stubs》,但我仍然不理解其中的区别。


当前回答

以下是我的理解……

如果您在本地创建测试对象并将其提供给本地服务,则使用的是模拟对象。 这将为您在本地服务中实现的方法提供测试。 它用于验证行为 当您从真正的服务提供者获得测试数据时(尽管是从接口的测试版本获得对象的测试版本),您是在使用存根 存根可以有逻辑来接受特定的输入并给出相应的输出来帮助您执行状态验证…

其他回答

这张幻灯片很好地解释了主要的区别。

*选自CSE 403第16讲,华盛顿大学(幻灯片由“Marty Stepp”制作)

存根是一个简单的伪对象。它只是确保测试顺利进行。 mock是更聪明的存根。您验证您的测试通过了它。

加上有用的答案,其中最强大的一点使用模拟比潜艇

如果合作者(主代码所依赖的合作者)不在我们的控制之下(例如来自第三方库), 在这种情况下,stub比mock更难编写。

Stub是实现组件接口的对象,但是Stub可以配置为返回适合测试的值,而不是返回调用时组件将返回的值。使用存根,单元测试可以测试一个单元是否可以处理来自合作者的各种返回值。在单元测试中使用存根而不是真正的合作者可以这样表示:

单元测试——>存根

单元测试——>单元——>存根

单元测试对结果和单元状态进行断言

首先,单元测试创建存根并配置其返回值。然后单元测试创建单元并在其上设置存根。现在,单元测试调用单元,而单元又调用存根。最后,单元测试对单元上的方法调用的结果进行断言。

A Mock is like a stub, only it also has methods that make it possible determine what methods where called on the Mock. Using a mock it is thus possible to both test if the unit can handle various return values correctly, and also if the unit uses the collaborator correctly. For instance, you cannot see by the value returned from a dao object whether the data was read from the database using a Statement or a PreparedStatement. Nor can you see if the connection.close() method was called before returning the value. This is possible with mocks. In other words, mocks makes it possible to test a units complete interaction with a collaborator. Not just the collaborator methods that return values used by the unit. Using a mock in a unit test could be expressed like this:

单元测试——>模拟

单元测试—>单元—>模拟

单元测试对单元的结果和状态进行断言

单元测试断言在mock上调用的方法

>>这里

Stubs vs. Mocks Stubs provide specific answers to methods calls ex: myStubbedService.getValues() just return a String needed by the code under test used by code under test to isolate it cannot fail test ex: myStubbedService.getValues() just returns the stubbed value often implement abstract methods Mocks "superset" of stubs; can assert that certain methods are called ex: verify that myMockedService.getValues() is called only once used to test behaviour of code under test can fail test ex: verify that myMockedService.getValues() was called once; verification fails, because myMockedService.getValues() was not called by my tested code often mocks interfaces