Kem*_*eia 3 python django datetime unit-testing python-mock
我有一个 Django 测试,我需要模拟 datetime.now(),因为它测试的视图使用 datetime.now()
\n\n我正在使用 Michael Foord 的模拟库,版本 1.0.1。
\n我正在寻找一种不使用其他库(例如 freezegun)的解决方案。
大多数例子都是这样的,这个导入 datetime 并覆盖它,但我正在导入 datetime.datetime 并尝试覆盖它,由于某种原因,这不起作用。
\n\n覆盖日期时间的工作原理:
\n\nimport mock\nimport datetime\n\nclass FixedDate(datetime.datetime):\n\n @classmethod\n def now(cls):\n return cls(2010, 1, 1)\n\n@mock.patch(\'datetime.datetime\', FixedDate)\ndef myTest():\n print(datetime.datetime.now())\n\nmyTest()\nRun Code Online (Sandbox Code Playgroud)\n\n但我想导入 datetime.datetime 并执行以下操作:
\n\nimport mock\nfrom datetime import datetime\n\nclass FixedDate(datetime):\n\n @classmethod\n def now(cls):\n return cls(2010, 1, 1)\n\n@mock.patch(\'datetime\', FixedDate)\ndef myTest():\n print(datetime.now())\n\nmyTest()\nRun Code Online (Sandbox Code Playgroud)\n\n这会导致 TypeError: Need a valid target to patch. 您提供了:“日期时间”。
\n\n模拟库还指出:
\n\n\n\n\ntarget 应该是 \xe2\x80\x98package.module.ClassName\xe2\x80\x99 形式的字符串。目标被导入,指定的对象被新对象替换,因此目标必须可以从您调用补丁的环境中导入。
\n
有什么方法可以只路径日期时间而不是 datetime.datetime ?
\n\n铌。我也看到了这个例子,但它对我不起作用,因为我没有一个返回日期时间的函数,但我的视图使用 datetime.now()
\n您应该patch在正在测试的模块中使用对象,而不是在进行测试的模块中。
基于您的代码的最小工作示例:
应用程序.py
from datetime import datetime
def my_great_func():
# do something
return datetime.now()
Run Code Online (Sandbox Code Playgroud)
test.py(注意如何datetime 修补 app.py)
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)
Run Code Online (Sandbox Code Playgroud)
测试执行结果:
$ 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/xyz/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 =======================
Run Code Online (Sandbox Code Playgroud)