模拟对象和Ruby的对象层次结构

时间:2014-05-01 18:47:56

标签: ruby object hierarchy

我使用MiniTest测试一些代码。在其中一组测试中,我有一个模拟对象返回罐装数据,如下所示:

require 'minitest/autorun'
require_relative '../object_under_test'

class Foo
     def method_returning_canned_data
         return canned_data
     end
end

class TestObjectUnderTestThatReliesOnFoo < Minitest::Test
     def test_something
     end
end

后来,我有一组测试实际Foo对象的测试。

require 'minitest/autorun'
require_relative '../foo'

class TestFoo < Minitest::Test
    def test_actual_object_foo
    end
end

问题是如果第一组测试首先运行,那么当运行实际Foo对象的测试时,模拟Foo对象首先在对象层次结构中并且方法被发送到它,这显然导致测试失败(除了没有测试正确的对象!)。

问题是,当我完成它后,如何从Ruby的层次结构中删除模拟Foo对象?或者......有没有更好的方法来返回固定数据以进行测试?

谢谢!

1 个答案:

答案 0 :(得分:0)

这总是一个棘手的问题。解决问题的一种快速方法是使用foo而不是load强制编译器加载require文件:

load '../foo.rb' #note the presence of the file extension

但是,为你的模拟类提供不同的名称并使用依赖注入来指示你的测试对象应该与哪个类进行交互通常是一个更好的主意。

class MockFoo
  #...
end

class ObjectUnderTest
  def method_that_depends_on_foo(foo_class = Foo)
    foo_class.do_something
    # ...
  end
end

在测试中,您可以使用method_that_depends_on_foo(MockFoo)调用该方法。根据您的方法实际执行的操作,可能有更好的方法来解决此问题,但重点是考虑如何在类之间分离严格的依赖关系。如果你想单独测试它们,它们需要是可以隔离的。