I'm using MiniTest to test some code. In one of these groups of tests, I have a mock object returning canned data like so:

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

Later, I have a group of tests that test the actual Foo object.

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

class TestFoo < Minitest::Test
    def test_actual_object_foo
    end
end

The problem is that if the first set of tests gets run first, the when the tests for the actual Foo object are run, the mock Foo object is first in object hierarchy and methods are being sent to it, which are obviously causing tests to fail (in addition to not testing the proper object!).

Question is, how do I remove the mock Foo object from Ruby's hierarchy when I'm done with it? Or...is there a better way to return canned data to test with?

Thanks!

有帮助吗?

解决方案

This is always a tricky problem. One quick way to solve it could be to force the compiler the load the foo file by using load instead of require:

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

However, it's usually a better idea to give your mock classes different names and use dependency injection to indicate which class your object under test should interact with.

class MockFoo
  #...
end

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

In your test, you would call the method using method_that_depends_on_foo(MockFoo). Depending on what your method actually does, there might be a better way to go about this, but the point is to think about how to decouple strict dependencies between your classes. If you want to test them in isolation, they need to be isolatable.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top