Django Test Mock Datetime Now
我有一个django测试,需要模拟datetime.now(),因为它测试的视图使用datetime.now()。
我正在使用迈克尔·福德的模拟库,版本1.0.1。我正在寻找一个不使用其他库(如Freezegun)的解决方案。
大多数例子都是这样的,这个导入日期时间并重写它,但是我正在导入datetime.datetime,我正在尝试重写它,因为某些原因,这个方法不起作用。
覆盖日期时间工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import mock import datetime class FixedDate(datetime.datetime): @classmethod def now(cls): return cls(2010, 1, 1) @mock.patch('datetime.datetime', FixedDate) def myTest(): print(datetime.datetime.now()) myTest() |
但我想导入datetime.datetime并执行如下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import mock from datetime import datetime class FixedDate(datetime): @classmethod def now(cls): return cls(2010, 1, 1) @mock.patch('datetime', FixedDate) def myTest(): print(datetime.now()) myTest() |
这会导致类型错误:需要有效的目标来修补。您提供了:"datetime"。
模拟图书馆还指出:
target should be a string in the form ‘package.module.ClassName’. The target is imported and the specified object replaced with the new object, so the target must be importable from the environment you are calling patch from.
是否有任何方法只访问datetime而不访问datetime.datetime?
铌。我也看到了这个例子,但它对我来说不起作用,因为我没有一个返回日期时间的函数,但是我的视图使用了日期时间。
您应该在正在测试的模块中,而不是在带有测试的模块中,使用cx1〔0〕对象。
基于代码的最小工作示例:
App.Py
1 2 3 4 5 | from datetime import datetime def my_great_func(): # do something return datetime.now() |
tests.py(注意
1 2 3 4 5 6 7 8 | from datetime import datetime from unittest import mock from app import my_great_func @mock.patch('app.datetime') def test_my_great_func(mocked_datetime): mocked_datetime.now.return_value = datetime(2010, 1, 1) assert my_great_func() == datetime(2010, 1, 1) |
测试执行结果:
1 2 3 4 5 6 7 8 9 10 11 | $ pytest -vvv tests.py ======================= test session starts ========================= platform linux -- Python 3.5.2, pytest-3.2.1, py-1.4.34, pluggy-0.4.0 cachedir: .cache rootdir: /home/kris/projects/tmp, inifile: plugins: mock-1.6.2, celery-4.1.0 collected 1 item tests.py::test_my_great_func PASSED ==================== 1 passed in 0.00 seconds ======================= |