I wanted to test a method on a class that didn't really depend on a lot of other stuff off the class. Or rather what it did depend on I had already turned into Mock objects with appropriate .return_values and asserting with .called etc. Problem was that the .__init__() method of the object invoked about half the application framework (option parsing, configuration file loading, setting up logging etc.). Firstly I don't really feel like testing all of that (hey, these are called unittests after all and those fuctionalities have their own!) and secondly then I had to worry about way too much, quite a lot to setup.
That's how the whacky idea of replacing the .__init__() method with a mock occurred to me:
class TestSomething(object): @mock.patch('module.Klass.__init__', mock.Mock(return_value=None)) def test_method(self): inst = module.Klass() inst.other_method = mock.Mock() inst._Klass__log = mock.Mock() # more of this inst.method() assert inst.other_method.called
The ugly side effects of deciding to mock away the .__init__() method like this is that I have to create mocks for more internal stuff. The one shown for exampls is normally provided by self.__log = logging.getLogger('foo').
I must admit that I'm still trying to find my way in how to use the mock module effectively and hence I'm not really sure how sane this approach is. One of my objections with this is that not only am I meddling with clearly hidden attributes of the class, but I also have to do this again and again for each test method. So the next revision (I'm using py.test as testing framework here btw):
cls._original_init_method = module.Klass.__init__
module.Klass.__init__ = mock.Mock(return_value=None)
module.Klass.__init__ = cls._original_init_method
def setup_method(self, method):
self.inst = module.Klass()
self.inst._Klass__log = mock.Mock()
# more of this
self.inst.other_method = mock.Mock()
This is actually workable and I'm testing what I want to test in a pretty isolated way. I'm still wondering whether I've gone insane or not tough. Is it reasonable to replace .__init__() by mock objects? Have other people done this?