我需要測試使用datetime.datetime.now()
的函數。什麼是最簡單的方法來做到這一點?如何用py.test monkeypatch python的datetime.datetime.now?
15
A
回答
19
您需要monkeypatch datetime.now函數。在下面的例子,我創建夾具,我以後可以在其他測試中重複使用:
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
3
這是我用現在覆蓋夾具(),但保持日期時間的其餘部分工作(RE:悟的問題)。
它沒有廣泛測試,但它確實解決了其他情況下使用datetime的問題。對我來說,保持Django ORM處理這些日期時間值非常重要(特別是isinstance(Freeze.now(), datetime.datetime) == True
)。
@pytest.fixture
def freeze(monkeypatch):
""" Now() manager patches datetime return a fixed, settable, value
(freezes time)
"""
import datetime
original = datetime.datetime
class FreezeMeta(type):
def __instancecheck__(self, instance):
if type(instance) == original or type(instance) == Freeze:
return True
class Freeze(datetime.datetime):
__metaclass__ = FreezeMeta
@classmethod
def freeze(cls, val):
cls.frozen = val
@classmethod
def now(cls):
return cls.frozen
@classmethod
def delta(cls, timedelta=None, **kwargs):
""" Moves time fwd/bwd by the delta"""
from datetime import timedelta as td
if not timedelta:
timedelta = td(**kwargs)
cls.frozen += timedelta
monkeypatch.setattr(datetime, 'datetime', Freeze)
Freeze.freeze(original.now())
return Freeze
也許脫離主題,但可能會派上用場的其他人到這個問題。該裝置,可「凍結」時間,然後隨意移動來回你的測試中:
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
11
from datetime import datetime
from freezegun import freeze_time # $ pip install freezegun
@freeze_time("Jan 14th, 2012")
def test_nice_datetime():
assert datetime.now() == datetime(2012, 1, 14)
freeze_time()
也可以用作上下文管理器。該模塊支持指定本地時區的UTC偏移量。
1
從其他的答案改編:
import datetime as dt
@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)
+0
哪裏'補丁'來了從?你錯過了進口? – sashk
相關問題
- 1. py.test在自定義funcargs中使用monkeypatch
- 2. 如何從Python使用py.test?
- 3. 如何monkeypatch suds.transport.Reply?
- 4. Python的嘲諷使用Py.Test
- 5. datetime.datetime.now()+ 1
- 6. 如何在py.test中的patchmonkey中設置類或模塊屬性
- 7. 如何安裝py.test?
- 8. 我如何將monkeypatch應用於GAE?
- 9. 在Python中,datetime.datetime.now()如何「不知道」日期時間對象?
- 10. Monkeypatch ActiveRecord :: FinderMethods
- 11. 如何使用Tox/Py.test顯示完整的Python跟蹤
- 12. 如何使用Python py.test實現Allure 2中的缺陷分類?
- 13. Python monkeypatch不能正確修補功能
- 14. datetime.datetime.now()返回舊值
- 15. pytest夾具參數與monkeypatch
- 16. 如何用另一個類的方法來裝飾(monkeypatch ...)一個Python類?
- 17. django的1.4 timezone.now()與datetime.datetime.now()
- 18. 我如何monkeypatch快速查看查找?
- 19. 如何重載或monkeypatch Request.remote_ip或Request.ip?
- 20. 如何導入pytest monkeypatch插件?
- 21. 用xvfb運行py.test
- 22. 如何安裝py.test-2.3?
- 23. 如何反轉py.test addopts?
- 24. 如何針對不同版本的python運行py.test?
- 25. Ubuntu上的py.test
- 26. 如何在不導入它們的情況下使用py.test夾具
- 27. 有可能monkeypatch函數體中引入的局部變量?
- 28. 如何正確導入py.test包?
- 29. 如何檢查py.test中的行爲?
- 30. 如何在Windows上安裝py.test
是否有可能只更換'now'方法? – satoru
這是有效的,但如果你是從「datetime import datetime」做的話。看看這裏的詳細信息:http://stackoverflow.com/questions/35431476/why-pythons-monkeypatch-doesnt-work-when-importing-a-class-instead-of-a-module – rgargente