2017-07-13 89 views
1

我試圖模擬datetime.now()的輸出來模擬時間的流逝。這裏是我想要做的事:Mocking datetime.now();模擬對象不被識別爲類

from datetime import datetime, timedelta 
from mock import Mock, patch 
from other_module import some_code 

tomorrow = Mock(spec=datetime) 
tomorrow.now = Mock(return_value=datetime.now() + timedelta(days=1)) 
with patch('other_module.datetime', tomorrow): 
    some_code() 

這將做工精細,除了some_code()使用圖書館,croniter,特異性採取datetime.datetime類作爲輸入,並檢查它的datetime.datetime一個子類。這是我遇到的問題;而datetime.datetime是一個類,我的模擬不是;它不被issubclass方法識別爲類類型。

如何確保我的模擬對象被識別爲一個類?

+0

我不確定你是如何構建你的unittests,但從技術上說,你應該嘲笑你從croniter調用的任何類/方法,因此它不影響你的單元測試。你的目標是測試調用'some_code()'的行爲。 – idjaw

+0

我想這是一個可能的解決方案,但這是集成測試的一部分,而不是單元測試,所以我試圖嘲笑儘可能少的東西 – syntacticmarmalade

+0

在集成測試中嘲弄似乎很奇怪。你是否試圖操縱時間來幫助你的集成測試來強制一些時間限制? – idjaw

回答

3

我不熟悉croniter,但freezegun可以幫助這個 - 它的斑塊的freezegun.api.FakeDatetime實例datetime.datetime所有引用,所以內some_code(),任何datetime.datetimes應該使用的freezegun.api.FakeDatetime實例。從經驗講,如果你使用凍槍來模擬時間的流逝,你也可以節省很多頭痛,並且間歇性的測試失敗。

from datetime import datetime, timedelta 
from freeze_gun import freeze_time 
from other_module import some_code 

fake_today = datetime.datetime(2017, 7, 11) 
with_freeze_time(fake_today): 
    some_code() 
# simulate passage of time to tomorrow 
with_freeze_time(fake_today + timedelta(days=1)) 
    some_code() 
+1

大聲笑。很高興看到其他人建議freezegun! :) – idjaw

+0

太棒了。謝謝 – syntacticmarmalade