Making A Wrapper For `mock.patch`
Some customized patches from mock.patch I want to use over and over without littering my test code with copy-pastes of the patch setup. e.g. this very handy patch of datetime.date,
Solution 1:
Here's a resource manager class that will do that for you. Since you might want to put it in a separate file from your test classes, it uses inspect
to look up the calling module, so that it can pass the correctly qualified target module name to mock.patch
.
import datetime
import inspect
# import mock according to your python versionclassmock_datetime(object):
def__init__(self, target, new_utcnow):
self.new_utcnow = new_utcnow
self.target = target
def__enter__(self):
calling_module = inspect.getmodule(inspect.stack()[1][0])
target_from_here = calling_module.__name__ + '.' + self.target
self.patcher = mock.patch(target_from_here)
mock_dt = self.patcher.start()
mock_dt.datetime.utcnow.return_value = self.new_utcnow.replace(tzinfo=None)
mock_dt.datetime.side_effect = lambda *args, **kw: datetime.datetime(*args, **kw)
return mock_dt
def__exit__(self, *args, **kwargs):
self.patcher.stop()
You can then invoke it with
withmock_datetime('mymodule.datetime', datetime.datetime(2016, 3, 23)):
assert mymodule.datetime.datetime.utcnow() == datetime.datetime(2016, 3, 23)
Solution 2:
The solution by @brandones is excellent! But I found it easier to use if you leave out the inspection, like this:
# testhelpers.pyimport unittest.mock as mock
import datetime
classMockDatetime():
def__init__(self, target, utcnow):
self.utcnow = utcnow
self.target = target
def__enter__(self):
self.patcher = mock.patch(self.target)
mock_dt = self.patcher.start()
mock_dt.datetime.utcnow.return_value = self.utcnow.replace(tzinfo=None)
mock_dt.datetime.side_effect = lambda *args, **kw: datetime.datetime(*args, **kw)
return mock_dt
def__exit__(self, *args, **kwargs):
self.patcher.stop()
# testhelpers_test.pyimport datetime
from testhelpers import MockDatetime
deftest__mock_datetime():
with MockDatetime('testhelpers_test.datetime', datetime.datetime(2019, 4, 29, 9, 10, 23, 1234)):
assert datetime.datetime.utcnow() == datetime.datetime(2019, 4, 29, 9, 10, 23, 1234)
Post a Comment for "Making A Wrapper For `mock.patch`"