![]() |
1
27
模拟对象不仅仅是具有已知值的对象。它是一个与复杂对象具有相同接口的对象,您不能在测试中使用该接口(如数据库连接和结果集),但可以在测试中控制该接口的实现。 有一些模拟框架允许您动态地创建这些对象,本质上允许您这样说:使用一个方法foo使我成为一个对象,该方法接受一个int并返回一个bool。当我通过0时,它应该返回真值。然后您可以测试使用foo()的代码,以确保它做出适当的反应。 马丁·福勒有一篇关于嘲弄的伟大文章: |
![]() |
2
9
想想拥有客户机和服务器软件的经典案例。要测试客户机,您需要服务器;要测试服务器,您需要客户机。这使得单元测试几乎不可能——不使用模拟。如果模拟服务器,则可以单独测试客户机,反之亦然。 嘲弄的重点不在于模仿它嘲弄的事物的行为。它更像是一个简单的状态机,其状态变化可以通过测试框架进行分析。因此,客户机模拟可能会生成测试数据,将其发送到服务器,然后分析响应。您期望对特定请求有一定的响应,这样您就可以测试是否得到它。 |
![]() |
3
6
我同意一切 @Lou Franco 你一定要读一下马丁·福勒关于测试双打的优秀文章,@lou franco给你指出。 任何测试double(fake、stub或mock)的主要目的是隔离被测试对象,以便单元测试只测试该对象(而不是它的依赖项以及它与之协作或交互的其他类型)。 提供您的对象所依赖的接口的对象可以用来代替实际的依赖关系,这样就可以放置期望,从而发生某些交互。这可能很有用,但是关于基于状态的测试和基于交互的测试存在一些争议。过度使用模拟期望将导致脆弱的测试。 测试双重化的另一个原因是删除对数据库、文件系统或其他类型的依赖性,这些依赖性对于设置或执行耗时的操作来说非常昂贵。这意味着您可以将对感兴趣的对象进行单元测试所需的时间降到最低。 |
![]() |
4
2
下面是一个例子:如果您正在编写填充数据库的代码,那么您可能需要检查某个特定方法是否向数据库添加了数据。 为测试设置数据库副本存在这样一个问题:如果假定在调用被测试方法之前没有记录,在调用之后又有一个记录,则需要将数据库回滚到以前的状态,从而增加运行测试的开销。 如果假设只有一条记录比以前多,那么它可能会与连接到同一数据库的第二个测试人员(甚至是同一代码中的第二个测试人员)发生冲突,从而导致依赖性并使测试变得脆弱。 模拟允许您保持测试彼此独立,并且易于设置。 这只是一个例子-我相信其他人可以提供更多。 我100%同意其他撰稿人关于这个主题的意见,特别是马丁·福勒的文章的建议。 |
![]() |
5
0
你可能对我们的书感兴趣,看 http://www.growing-object-oriented-software.com/ . 它是在Java中,但是这些想法仍然适用。 |