了解存根,假货和嘲笑。

时间:2013-02-15 09:48:35

标签: unit-testing mocking tdd stubs

我刚刚开始阅读Professional Test Driven Development with C#: Developing Real World Applications with TDD

我很难理解存根,假货和嘲笑。从我到目前为止的理解,它们是用于单元测试项目的假对象,而mock是一个带有条件逻辑的存根。

我认为我已经接受的另一件事是,模拟与依赖注入有某种联系,这是我昨天才明白的一个概念。

我没有得到的是我实际使用它们的原因。我似乎无法在网上找到任何正确解释它们的具体例子。

有人可以向我解释这个概念吗?

3 个答案:

答案 0 :(得分:21)

正如我过去所读到的,这就是我认为每个术语代表的内容

<强>存根

在这里,您将方法的结果存根到已知值,只是让代码运行没有问题。例如,假设您有以下内容:

public int CalculateDiskSize(string networkShareName)
{
    // This method does things on a network drive.
}

你不关心这个方法的返回值是什么,它不相关。此外,如果网络驱动器不可用,它可能会在执行时导致异常。因此,您应该对结果进行存根,以避免该方法的潜在执行问题。

所以你最终做了类似的事情:

sut.WhenCalled(() => sut.CalculateDiskSize()).Returns(10);

<强>假

假冒你正在返回假数据,或者创建一个虚假的对象实例。一个典型的例子是存储库类。采取这种方法:

public int CalculateTotalSalary(IList<Employee> employees) { }

通常,上述方法将传递从数据库中读取的员工集合。但是,在单元测试中,您不希望访问数据库。所以你创建一个假的员工名单:

IList<Employee> fakeEmployees = new List<Employee>();

然后,您可以向fakeEmployees添加项目并断言预期结果,在这种情况下是总薪水。

<强>嘲笑

使用模拟对象时,您打算在这些模拟对象上验证某些行为或数据。例如:

您想验证在测试运行期间是否执行了特定方法,这是使用Moq模拟框架的一般示例:

public void Test()
{
    // Arrange.
    var mock = new Mock<ISomething>();

    mock.Expect(m => m.MethodToCheckIfCalled()).Verifiable();

    var sut = new ThingToTest();

    // Act.
    sut.DoSomething(mock.Object);

    // Assert
    mock.Verify(m => m.MethodToCheckIfCalled());
}

希望上述内容有助于澄清一些事情。

编辑: Roy Osherove是测试驱动开发的知名倡导者,他有一些非常好的信息。您可能会发现它非常有用:

http://artofunittesting.com/

答案 1 :(得分:3)

它们是Test Double的所有变体。这是一个非常好的参考,解释了它们之间的差异:http://xunitpatterns.com/Test%20Double.html

另外,来自Martin Fowler的帖子:http://martinfowler.com/articles/mocksArentStubs.html

  

Meszaros使用术语Test Double作为任何类型的通用术语   假装用于代替真实对象的对象用于测试目的。   这个名字来自电影中特技双人的概念。 (之一   他的目的是避免使用已经广泛使用的任何名称。)   Meszaros然后定义了四种特殊的双重类型:

     
      
  1. 虚拟对象:传递但从未实际使用过。通常他们   仅用于填充参数列表。
  2.   
  3. 假对象实际上有工作实现,但通常需要一些快捷方式   它们不适合生产(内存数据库是一个很好的   例子)。
  4.   
  5. Stubs为测试期间拨打的电话提供固定答案,   通常根本没有回应任何程序以外的任何东西   为了测试。存根也可以记录有关呼叫的信息,例如   一个电子邮件网关存根,可以记住它“发送”的消息,或者可能   只发送了多少条消息。
  6.   
  7. 模拟是我们在这里所讨论的:预编程的对象具有期望形成的对象   他们期望收到的电话的规范。
  8.         

    在这些双打中,只有嘲讽坚持行为验证。该   其他双打可以,通常也可以使用状态验证。嘲弄   实际上在运动阶段表现得像其他双打一样   他们需要让SUT相信它正在与它的真实交谈   协作者。

答案 2 :(得分:0)

这个PHP单元的手册对我的介绍很有帮助:

“有时很难测试被测系统(SUT),因为它依赖于在测试环境中无法使用的其他组件。这可能是因为它们不可用,它们不会返回结果测试所需要的或因为执行它们会产生不良副作用。在其他情况下,我们的测试策略要求我们对SUT的内部行为有更多的控制或可见性。“更多:https://phpunit.de/manual/current/en/test-doubles.html

我在寻找“测试双打”时找到了更好的“介绍”,因为嘲笑,假货,存根和其他人都知道。