Colin Riddell
Colin Riddell

Reputation: 427

Python unittest Mock patch object not methods

I am having trouble getting my head around unit testing with Mock in Python. I have a method start_thing() in a class I'd like to test:

class ComplexClass:
   def __init__(self, lots, of, args):
       self.lots = lots
       ..

   def start_thing(self):
        import pdb; pdb.set_trace()
        print "some error!!"
        assert False

The class this belongs to is quite complex and a pain to try and mock manually. That is why I started to look at using Mock.

I would like to setup a mock that Mocks an instance of this class to make it easy to run a unittest, but not mock the method start_thing() so that the real start_thing() implementation is tested, not a mocked version .. so I created this:

class TestComplexClass(TestCase):
     @patch.object(module.ComplexClass, 'start_thing')
     def test_start_thing(self, mock_method):
        ComplexClass.start_thing()

When running my test the debug trace, assert or print are not hit in my real method start_thing(), which suggests I have mocked the class and the method - where I just want to mock the object and test the real methods. What am I doing wrong here? Is that possible?

I have found lots of examples with Mock showing how to create a mock version of the method I want to test, which I think is kind of pointless since I don't want to check if it's being called correctly, rather I want to test the implementation in the real code, and mock the class it belongs to so it's easier to create.

Perhaps there's something I don't understand about the Mock testing idea as a whole?

Upvotes: 4

Views: 2532

Answers (1)

Dan
Dan

Reputation: 1884

I don't think you want to mock that class but to stub it out, ex:

class ComplexClassStub(ComplexClass):
  def __init__(self):
    self.lots = None
    self.the_rest_of_the_args = None # Now your complex class isn't so complex.

class ComplexClassTest(unittest.TestCase):
  def Setup(self):
    self.helper = ComplexClassStub()

  def testStartThing(self):
    with mock.patch.object(self.helper, 'SomethingToMock') as something_mocked:
      expected = 'Fake value'
      actual = self.helper.start_thing()
      self.assertEqual(expected, actual)
      something_mocked.assert_called_once_with()

Upvotes: 3

Related Questions