Mock、Stub和Factory Girl有什么区别?

32

我对rspec和整个TDD方法都比较陌生。请有人解释一下模拟和存根之间的区别。我们在什么情况下使用它们,什么情况下使用Factory Girl在测试用例中创建对象?

2个回答

17
你可以把Mock(或Double)视为一个假对象。当你在测试时需要使用一个不易在测试中使用的对象时,可以使用Mock作为这个对象行为的估计值,并围绕它工作。Stub也可以以类似的方式在对象的单个方法上使用。
这里有一个非常牵强的例子,同时使用了大量Mock和Stub:
class Client
  def connect_to_server
    if Server.connect.status == 'bad'
      show_an_error
    else
      do_something_else
    end
  end
  def do_something_else; end
  def show_an_error; end
end

context "failure" do
  it "displays an error" do
    bad_network_response = double("A bad response from some service", :status => 'bad')
    Server.should_receive(:connect).and_return(bad_network_response)

    client = Client.new
    client.should_receive(:show_an_error)
    client.connect_to_server
  end
end

使用太多的Mock或Stub可能并不是一个好主意。这基本上是在你的测试中掩盖了你代码的某些部分,但对于一些困难/罕见的测试场景来说,这是一个简单的解决方案。

Factory Girl 用于为测试生成数据。您可以使用工厂作为创建模型实例的配方,这对于需要测试大量测试数据的情况非常有用。在这种情况下,使用fixture将无法工作,显式创建复杂对象则可能很繁琐。


1
我可能错了,但我认为你对存根只存在于方法上的看法是错误的。你可以有存根对象或模拟对象,也可以有存根方法或模拟方法。区别在于你如何使用它们。存根只是为了让测试正常工作而不实际调用另一个依赖项。模拟也是一样,但调用是必需的并且是测试的一部分。你可以有一个既有存根又有模拟的虚假对象。Rspec现在甚至称它们为“double”,而不是mock。 - fregas

17

你的首要目标是阅读Martin Fowler著名文章:Mocks are not Stubs

编辑

MockStubTest Doubles中的两种类型(Mezaros术语)。测试替身通常用于模拟系统测试(或类测试)需要的依赖关系,以便可以从其依赖项中隔离地测试SUT / CUT。 (注意-精确术语可能会引起一些争议,例如如Jeff所提到

来源:维基百科

示例

  • 当SUT调用时,存根方法可以返回一个常量值,例如针对SUT的特定测试用例。
  • 类似Mockito(Java)和Moq(.Net)的框架允许您动态构建针对依赖项接口的模拟类,仅需最少量的代码,并提供验证SUT与模拟正确互动的能力,例如通过检查SUT正确调用了模拟的方法的次数以及使用了正确的参数。

*免责声明-我不是Ruby开发人员


6
当你读完那篇文章后,可以继续阅读关于“嘲弄TDD”的内容:http://avdi.org/devblog/2011/09/06/making-a-mockery-of-tdd/。 - Jason Lewis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接