How to mock python's datetime.now() in a class method for unit testing?
我正在尝试为一个类编写测试,该类的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 | import datetime import pytz class MyClass: def get_now(self, timezone): return datetime.datetime.now(timezone) def do_many_things(self, tz_string='Europe/London'): tz = pytz.timezone(tz_string) localtime_now = self.get_now(tz) ... return things |
我想测试它,为此我需要确保
我已经阅读了很多在测试中使用模拟的例子,但是还没有找到与我需要的完全相同的东西,而且我也不知道如何在测试中使用它。
我将
你可以使用Freezegun:
1 2 3 4 5 6 7 | from freezegun import freeze_time def test(): assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) with freeze_time("2012-01-14"): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) |
它基本上模拟了
您将创建一个返回特定日期时间的函数,该日期时间本地化为传入的时区:
1 2 3 4 5 6 7 8 9 10 | import mock def mocked_get_now(timezone): dt = datetime.datetime(2012, 1, 1, 10, 10, 10) return timezone.localize(dt) @mock.patch('path.to.your.models.MyClass.get_now', side_effect=mocked_get_now) def your_test(self, mock_obj): # Within this test, `MyClass.get_now()` is a mock that'll return a predictable # timezone-aware datetime object, set to 2012-01-01 10:10:10. |
这样,您就可以测试是否正确地处理了所生成的时区感知日期时间;其他地方的结果应该显示正确的时区,但具有可预测的日期和时间。
当模拟
我使用的是
1 2 3 | class SpoofDate(date): def __new__(cls, *args, **kwargs): return date.__new__(date, *args, **kwargs) |
…
1 2 3 4 5 | from mock import patch @patch('some.module.date', SpoofDate) def testSomething(self): SpoofDate.today = classmethod(lambda cls : date(2012, 9, 24)) |
其中
我将使用"testfactures"包中的帮助程序模拟您现在调用的日期时间类():
http://packages.python.org/testfactures/datetime.html日期时间
这样,您就可以随时测试您拥有的所有案例。