Python unittest Mock patch object not methods
Question: 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?


Answer: 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()
    

