为…做包装`模拟补丁`

2024-04-27 04:54:47 发布

您现在位置:Python中文网/ 问答频道 /正文

一些来自mock.patch的定制补丁我想反复使用,而不必把我的测试代码与补丁设置的复制粘贴一起丢弃。e、 g.this very handy patch of ^{},它适应于datetime,可以用

with patch('mymodule.datetime') as mock_datetime:
    mock_datetime.datetime.utcnow.return_value = datetime.datetime(2010, 10, 8, 9, 10)
    mock_date.datetime.side_effect = lambda *args, **kw: datetime.datetime(*args, **kw)

如何将此功能打包到一个单行呼叫中?在


Tags: ofdatetimeaswithargsthismockvery
2条回答

下面是一个资源管理器类,它将为您实现这一点。由于您可能希望将其放在与测试类不同的文件中,因此它使用inspect查找调用模块,以便它可以将正确限定的目标模块名称传递给mock.patch。在

import datetime
import inspect
# import mock according to your python version

class mock_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()

然后可以使用

^{pr2}$

brandones的解决方案很好!但我发现如果你不检查的话,使用起来更方便,比如:

# testhelpers.py
import unittest.mock as mock
import datetime

class MockDatetime():
    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.py
import datetime
from testhelpers import MockDatetime

def test__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)

相关问题 更多 >