Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何monkeypatch python';s datetime.datetime.now是否使用py.test?_Python_Datetime_Mocking_Pytest - Fatal编程技术网

如何monkeypatch python';s datetime.datetime.now是否使用py.test?

如何monkeypatch python';s datetime.datetime.now是否使用py.test?,python,datetime,mocking,pytest,Python,Datetime,Mocking,Pytest,我需要测试使用datetime.datetime.now()的函数。最简单的方法是什么?您需要使用monkeypatch datetime.now函数。在下面的示例中,我正在创建夹具,稍后可以在其他测试中重复使用: import datetime import pytest FAKE_TIME = datetime.datetime(2020, 12, 25, 17, 5, 55) @pytest.fixture def patch_datetime_now(monkeypatch):

我需要测试使用
datetime.datetime.now()的函数。最简单的方法是什么?

您需要使用monkeypatch datetime.now函数。在下面的示例中,我正在创建夹具,稍后可以在其他测试中重复使用:

import datetime
import pytest

FAKE_TIME = datetime.datetime(2020, 12, 25, 17, 5, 55)

@pytest.fixture
def patch_datetime_now(monkeypatch):

    class mydatetime:
        @classmethod
        def now(cls):
            return FAKE_TIME

    monkeypatch.setattr(datetime, 'datetime', mydatetime)


def test_patch_datetime(patch_datetime_now):
    assert datetime.datetime.now() == FAKE_TIME

这是我用来覆盖now()但保持datetime其余部分工作的装置(关于:satoru的问题)

它没有经过广泛的测试,但它确实解决了在其他上下文中使用datetime的问题。对我来说,让Django ORM使用这些日期时间值(特别是
isinstance(Freeze.now(),datetime.datetime)==True
)非常重要

也许是离题了,但对于其他人来说,这可能是一个有用的问题。此夹具允许“冻结”时间,然后在测试中随意来回移动:

def test_timesensitive(freeze):
    freeze.freeze(2015, 1, 1)
    foo.prepare()  # Uses datetime.now() to prepare its state
    freeze.delta(days=2)
    # Does something that takes in consideration that 2 days have passed
    # i.e. datetime.now() returns a date 2 days in the future
    foo.do_something()
    assert foo.result == expected_result_after_2_days
有:


冻结时间()
也可以用作上下文管理器。模块支持指定本地时区UTC偏移。

根据其他答案改编:

import datetime as dt
from contextlib import contextmanager
from unittest.mock import patch

@contextmanager
def mocked_now(now):
    class MockedDatetime(dt.datetime):
        @classmethod
        def now(cls):
            return now

    with patch("datetime.datetime", MockedDatetime):
        yield
用法如下:

def test_now():
    with mocked_now(dt.datetime(2017, 10, 21)):
        assert dt.datetime.now() == dt.datetime(2017, 10, 21)

使用MagicMock(wrap=datetime.datetime)怎么样

此方法模拟
datetime.datetime.now()
,但其他方法与原始的
datetime.datetime
方法相同

from unittest.mock import MagicMock

def test_datetime_now(monkeypatch):
    import datetime
    FAKE_NOW = datetime.datetime(2020, 3, 11, 14, 0, 0)
    datetime_mock = MagicMock(wraps=datetime.datetime)
    datetime_mock.now.return_value = FAKE_NOW
    monkeypatch.setattr(datetime, "datetime", datetime_mock)

    assert datetime.datetime.now() == FAKE_NOW

    # the other methods are available
    assert datetime.datetime.fromisoformat("2020-03-01T00:00:00") == datetime.datetime(2020, 3, 1, 0, 0, 0)

这里使用
@pytest.fixture
方法

import datetime
from unittest.mock import MagicMock

import pytest

FAKE_NOW = datetime.datetime(2020, 3, 11, 14, 0, 0)


@pytest.fixture()
def mock_datetime_now(monkeypatch):
    datetime_mock = MagicMock(wraps=datetime.datetime)
    datetime_mock.now.return_value = FAKE_NOW
    monkeypatch.setattr(datetime, "datetime", datetime_mock)


def test_datetime_now2(mock_datetime_now):
    assert datetime.datetime.now() == FAKE_NOW

    assert datetime.datetime.fromisoformat("2020-03-01T00:00:00") == datetime.datetime(2020, 3, 1, 0, 0, 0)


是否可以只替换
now
方法?这是可行的,但如果您执行“从日期时间导入日期时间”,则不可行。在这里查看详细信息:我能够调整这个答案并修补
utcnow
修补程序的来源?您错过导入了吗?从unittest.mock import patch@sashkYou也错过了导入contextmanager:
从contextlib导入contextmanager
您忘记导入
MagicMock
。所以按原样编码是行不通的。谢谢你的评论!我修复了它。这将破坏使用
isinstance(value,datetime.datetime)
的代码,例如,tortoise orm。
from unittest.mock import MagicMock

def test_datetime_now(monkeypatch):
    import datetime
    FAKE_NOW = datetime.datetime(2020, 3, 11, 14, 0, 0)
    datetime_mock = MagicMock(wraps=datetime.datetime)
    datetime_mock.now.return_value = FAKE_NOW
    monkeypatch.setattr(datetime, "datetime", datetime_mock)

    assert datetime.datetime.now() == FAKE_NOW

    # the other methods are available
    assert datetime.datetime.fromisoformat("2020-03-01T00:00:00") == datetime.datetime(2020, 3, 1, 0, 0, 0)

import datetime
from unittest.mock import MagicMock

import pytest

FAKE_NOW = datetime.datetime(2020, 3, 11, 14, 0, 0)


@pytest.fixture()
def mock_datetime_now(monkeypatch):
    datetime_mock = MagicMock(wraps=datetime.datetime)
    datetime_mock.now.return_value = FAKE_NOW
    monkeypatch.setattr(datetime, "datetime", datetime_mock)


def test_datetime_now2(mock_datetime_now):
    assert datetime.datetime.now() == FAKE_NOW

    assert datetime.datetime.fromisoformat("2020-03-01T00:00:00") == datetime.datetime(2020, 3, 1, 0, 0, 0)