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`"