I cannot understand how mock patch works and if does it able to solve my problem.
I have 3 files: communication with external interface (a.py), business logic (b.py) and tests (test.py). I want to patch external interface that is used by business logic while running tests.
a.py:
class SomeProductionClassINeedPatch(object):
name = 'Production Class (communication with some external service)'
def do_something(self):
print '<some feature with external service>'
b.py:
import mock
from src.tmp.mocks.a import SomeProductionClassINeedPatch
class WorkingClass(object):
def some_method_that_uses_external_class(self, *args):
external = self._external
external.do_something()
@property
def _external(self):
if not hasattr(self, '_ext_obj' or not self._ext_obj):
self._ext_obj = SomeProductionClassINeedPatch()
print isinstance(self._ext_obj, mock.MagicMock) # False
return self._ext_obj
b = WorkingClass()
b.some_method_that_uses_external_class()
test.py:
import mock
from src.tmp.mocks.b import WorkingClass # class I want to test
@mock.patch('src.tmp.mocks.a.SomeProductionClassINeedPatch')
def test_some_method_of_working_class(external_mock=None, *args):
o = WorkingClass()
o.some_method_that_uses_external_class() # external interface wasn't patched: <some feature with external service> - but I need mock here!
print '<test> - '+str(isinstance(o._external, mock.MagicMock)) # False
test_some_method_of_working_class()
I expect that calling o.some_method_that_uses_external_class() in test.py will not actually use external interface, but mock object. But seems still actual object is used.
Also when I check instance of external interface object either in test.py or in b.py - I cannot make them to pass isinstance(object, MagicMock) check, it always return false. Even if I try to apply the same patch in b.py (as class decorator). What am I doing wrong?
I use python 2.7 and mock library 1.0 by Michael Foord if that matters.