如何在pytest中模拟/设置系统日期?
在我的一些测试中,我遇到了一个问题,就是它们在Travis上因为时间和时区的问题而失败。所以我想在我的测试中模拟系统时间。我该怎么做呢?
4 个回答
4
我更喜欢用这段代码。
from unittest.mock import MagicMock
@pytest.fixture
def mocking_datetime_now(monkeypatch):
datetime_mock = MagicMock(wrap=datetime.datetime)
datetime_mock.now.return_value = datetime.datetime(2020, 3, 11, 0, 0, 0)
monkeypatch.setattr(datetime, "datetime", datetime_mock)
@pytest.fixture
def setup_db(company, company_user, mocking_datetime_now):
assert datetime.datetime.now() == datetime.datetime(2020, 3, 11, 0, 0, 0)
18
你可以通过两种方式来实现这个目标:
创建一个函数,代替
datetime.datetime.now()
的调用,正如Bruno所建议的,不过这里有不同的实现方式:import os import datetime def mytoday(): if 'MYDATE' in os.environ: return datetime.datetime.strptime(os.getenv('MYDATE'), '%m-%d-%Y').date() else: return datetime.date.today()
然后,在你的测试中,你只需要修改环境变量:
import datetime def test_patched_date(monkeypatch): monkeytest.setenv('MYDATE', '05-31-2014') assert datetime.date.today() == datetime.date(2014, 5, 31)
直接修改
datetime
函数:import datetime import pytest FAKE_TIME = datetime.datetime(2020, 12, 25, 17, 05, 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
29
据我所知,你不能模拟内置的方法。
我常用的一种方法是稍微修改一下我的代码,不直接使用 datetime
来获取日期,而是使用一个包装函数:
# mymodule.py
def get_today():
return datetime.date.today()
这样在测试的时候就很简单地可以 mock
它了:
def test_something():
with mock.patch('mymodule.get_today', return_value=datetime.date(2014, 6, 2)):
...
你也可以使用 freezegun 这个模块。