Mock datetime.datetime.now() while unit testing
1 2 3 4 5 6 | @pytest.mark.parametrize("test_input,expected_output", data) def test_send_email(test_input, expected_output): emails = SendEmails(email_client=MagicMock()) emails.send_email = MagicMock() emails.send_new_email(*test_input) emails.send_email.assert_called_with(*expected_output) |
我正在寻找模拟datetime.datetime.now(),它在send_new_email方法中调用。但我不确定该怎么做。
我尝试创建一个新的日期时间对象
1 2 | datetime_object = datetime.datetime.strptime('Jun 1 2017 1:33PM', '%b %d %Y %I:%M%p') |
然后重写datetime.datetime.now。
1 | datetime.datetime.now = MagicMock(return_value=datetime_object) |
但是,我得到了错误
TypeError: can't set attributes of built-in/extension type 'datetime.datetime'
这个问题被标记为python的副本:试图模拟datetime.date.today(),但不起作用
python:试图模拟datetime.date.today(),但不起作用
我已经尝试过这个解决方案,但无法使它工作。由于项目要求,我无法安装Freezegun。
我在测试文件中创建了一个新类
1 2 3 4 5 | class NewDate(datetime.date): @classmethod def today(cls): return cls(2010, 1, 1) datetime.date = NewDate |
但是我不知道如何让sendmails类使用这个。
您可以替换整个类:
1 2 3 4 5 | _FAKE_TIME = 0 class _FakeDateTime(datetime.datetime): @staticmethod def now(): return _FAKE_TIME |
然后使用它:
1 2 | _FAKE_TIME = whatever datetime.datetime = _FakeDateTime |
该类需要一些改进,比如比较运算符,以使fakedatetime与datetime具有可比性,但它应该可以工作。