伪造,嘲弄和剔除有什么区别?

我知道我如何使用这些术语,但是我想知道是否有可接受的用于单元测试的伪造嘲讽残片定义? 你如何为你的测试定义这些? 描述你可能会使用每种情况。

以下是我如何使用它们:

Fake :实现接口但包含固定数据和无逻辑的类。 根据实施情况简单地返回“好”或“坏”数据。

模拟(Mock) :一个实现接口的类,允许动态设置值以返回/异常以从特定方法抛出,并提供检查特定方法是否被调用/未调用的能力。

存根 :就像一个模拟类,除了它没有提供验证方法被调用/未被调用的能力。

模拟和存根可以由手工生成或由模拟框架生成。 手工生成假类。 我主要使用mock来验证我的类和相关类之间的交互。 一旦我验证了交互并且正在测试通过我的代码的替代路径,我使用存根。 我使用假类主要是为了抽象出数据的依赖关系,或者当模拟/存根过于繁琐而无法每次设置时。


你可以得到一些信息:

从马丁福勒关于模拟和存根

对象实际上有工作实现,但通常采取一些捷径,使其不适合生产

存根提供了在测试过程中进行的调用的解答,通常对测试之外的任何事情都没有响应。 存根还可以记录关于呼叫的信息,例如记录其“发送”消息的电子邮件网关存根,或者可能仅记录“发送”的消息数量。

嘲笑是我们在这里讨论的内容:预先编制了预期的对象,这些预期形成了预期要接收的呼叫的规范。

从xunitpattern:

Fake :我们获取或构建一个由SUT依赖的组件提供的相同功能的轻量级实现,并指示SUT使用它而不是真实的组件。

存根(stub) :该实现被配置为响应来自SUT的调用,该调用具有在SUT内执行未测试代码的值(或例外)(参见第X页的生产错误)。 使用测试桩的关键指标是由于无法控制SUT的间接输入而导致未测试代码

模拟对象 ,实现与SUT(被测系统)所依赖的对象相同的接口。 当我们需要进行行为验证以避免由于无法观察调用SUT方法的副作用而导致未经测试的要求(请参阅第X页的生产错误)时,我们可以使用模拟对象作为观察点。

亲自

我尝试使用:Mock和Stub进行简化。 当它是一个返回一个设置为被测类的值的对象时,我使用Mock。 我使用存根来模拟要测试的接口或抽象类。 事实上,你称之为无关紧要,它们都是不在生产中使用的类,并且被用作测试工具类。


存根 - 提供预定义方法调用答案的对象。

模拟 - 您设定期望的对象。

- 一个功能有限的对象(用于测试),例如伪造的Web服务。

Test Double是存根,嘲讽和假货的总称。 但非正式地,你会经常听到人们简单地称他们为嘲笑。


我很惊讶这个问题已经存在了很长时间,没有人提供基于Roy Osherove的“单元测试的艺术”的答案。

在“3.1引言存根”中定义了一个存根:

存根是系统中现有依赖关系(或协作者)的可控替代品。 通过使用存根,您可以测试代码而不直接处理依赖关系。

并且定义了存根和嘲讽之间的区别如下:

关于模拟与存根的主要问题是模拟和存根一样,但是你对模拟对象断言,而你并不坚持存根。

假只是用于存根和嘲讽的名称。 例如,当你不关心存根和嘲讽之间的区别时。

Osherove区分存根和嘲笑的方式意味着任何用作测试假的类都可以是存根或模拟。 它是用于特定测试的完全取决于您如何在测试中编写检查。

  • 当你的测试检查被测试的类中的值,或者实际上除了假的地方以外的任何地方,假的被用作存根。 它只是为被测试的类提供了值,可以直接通过调用返回的值,也可以通过调用副作用(某些状态)间接调用。
  • 当你的测试检查假的值时,它被用作模拟。
  • 类FakeX用作存根的测试示例:

    const pleaseReturn5 = 5;
    var fake = new FakeX(pleaseReturn5);
    var cut = new ClassUnderTest(fake);
    
    cut.SquareIt;
    
    Assert.AreEqual(25, cut.SomeProperty);
    

    fake实例被用作存根,因为Assert根本不使用fake

    将测试类别X用作模拟的测试示例:

    const pleaseReturn5 = 5;
    var fake = new FakeX(pleaseReturn5);
    var cut = new ClassUnderTest(fake);
    
    cut.SquareIt;
    
    Assert.AreEqual(25, fake.SomeProperty);
    

    在这种情况下, Assert检查fake的价值,使得假冒为假。

    现在,这些例子当然是非常有意思的,但我认为这个区别很有价值。 它让你意识到你如何测试你的东西以及测试的依赖关系。

    我同意Osherove的那个

    从纯粹的可维护性角度来看,在使用mock的测试中,创建比不使用它们更麻烦。 这是我的经验,但我总是在学习新的东西。

    断言这个假是你真正想避免的,因为它使得你的测试高度依赖于一个并非被测试的类的实现。 这意味着类ActualClassUnderTest的测试可以开始破坏,因为ClassUsedAsMock的实现ClassUsedAsMock更改。 这给我发出了一种恶臭。 ActualClassUnderTest测试应该最好只在ActualClassUnderTest更改时才会中断。

    我意识到写作对抗假冒是一种常见做法,特别是当你是一个模仿者类型的TDD用户时。 我想我与马丁福勒在古典主义阵营中坚定不移(见Martin Fowler的“Mocks is not Stubs”),并且像Osherove尽可能地避免了交互测试(这只能通过声称对付假)。

    有趣的阅​​读为什么你应该避免这里定义的嘲笑,谷歌为“fowler嘲弄古典主义”。 你会发现很多意见。

    链接地址: http://www.djcxy.com/p/67703.html

    上一篇: What's the difference between faking, mocking, and stubbing?

    下一篇: Storing/Reading sensitive data from Java program