在 Python 2.7 的 unittest.TestCase 中途模拟 datetime.now()
Mocking datetime.now() midway through a unittest.TestCase in Python 2.7
我正在尝试测试一些去抖动逻辑 - 这些是我 运行 对 Google App Engine webapp 的本地单元测试,使用 2.7 运行time 环境。我所有的其他测试都进行得很顺利,但是这个让我难住了!
def testThat_emailDebouncingWorks(self):
# Do something, it triggers an email.
doSomething()
self.assertEqual(emails_sent, 1)
# Do something again, the new email is debounced.
doSomething()
self.assertEqual(emails_sent, 1)
# After an hour, the emails should start working again...
mockWaitingAnHour()
doSomething()
self.assertEqual(emails_sent, 2)
# ... and so should the debouncing.
doSomething()
self.assertEqual(emails_sent, 2)
测试中的文件记录了使用 datetime.now() 发送电子邮件的时间,然后在以后的所有尝试中重新 运行s datetime.now() 和 returns如果不到一个小时就早点。
有两件事出错了:
我认为 unittest 库只在 3.X 中添加了模拟支持,我并不热衷于更新我的整个应用程序。
即使我使用的是 3.X,我看到的所有示例都是关于为整个测试用例伪造日期时间响应(在测试定义之上使用模拟装饰器)。而我想在测试中途更改该行为,而不是针对整个案例。
有什么建议吗?提前致谢!
好的,我已经深入了解了,想为在 Google 上找到此内容的任何人记录答案;)
1.在 AppEngine 上为 Python 2.7
启用模拟
您需要按照说明从 the official docs 复制第三方库(在我们的例子中,"mock")。值得注意的是,在Ubuntu上,建议的命令:
pip install -t lib/ mock
会失败。你会得到这样的错误:
DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base
这与 Ubuntu 的奇怪冲突有关,该冲突似乎多年来一直未解决,您会看到很多人建议使用 virtualenv 解决方法。我添加了 --system 标志:
pip install --system -t lib/ mock
而且效果很好。请记住按照 appengine_config 的其余说明进行操作,您应该设置好了。 "import mock" 是一个很好的检查方法。
2。模拟 datetime.now() 调用
我的测试模块使用:
from datetime import datetime
在我的测试模块中,导入一些东西:
from mock import patch, Mock
import my_module #Also known as my_module.py
import datetime
那么实际测试用例:
@patch.object(my_module, 'datetime', Mock(wraps=datetime.datetime))
def testThat_myModule_debouncesEmails(self):
fake_time = datetime.datetime.now()
# This is the first time the thing happened. It should send an email.
doSomething()
self.assertEqual(1, emails_sent)
# Five minutes later, the thing happens again. Should be debounced.
fake_time += datetime.timedelta(minutes=5)
my_module.datetime.now.return_value = fake_time
doSomething()
self.assertEqual(1, emails_sent)
# Another 56 minutes pass, the thing happens again. An hour has elapsed, so don't debounce.
fake_time += datetime.timedelta(minutes=56)
my_module.datetime.now.return_value = fake_time
doSomething()
self.assertEqual(2, emails_sent)
# Give it another 15 minutes to check the debouncing kicks back in.
fake_time += datetime.timedelta(minutes=15)
my_module.datetime.now.return_value = fake_time
doSomething()
self.assertEqual(2, emails_sent)
希望这对某人有所帮助!
我正在尝试测试一些去抖动逻辑 - 这些是我 运行 对 Google App Engine webapp 的本地单元测试,使用 2.7 运行time 环境。我所有的其他测试都进行得很顺利,但是这个让我难住了!
def testThat_emailDebouncingWorks(self):
# Do something, it triggers an email.
doSomething()
self.assertEqual(emails_sent, 1)
# Do something again, the new email is debounced.
doSomething()
self.assertEqual(emails_sent, 1)
# After an hour, the emails should start working again...
mockWaitingAnHour()
doSomething()
self.assertEqual(emails_sent, 2)
# ... and so should the debouncing.
doSomething()
self.assertEqual(emails_sent, 2)
测试中的文件记录了使用 datetime.now() 发送电子邮件的时间,然后在以后的所有尝试中重新 运行s datetime.now() 和 returns如果不到一个小时就早点。
有两件事出错了:
我认为 unittest 库只在 3.X 中添加了模拟支持,我并不热衷于更新我的整个应用程序。
即使我使用的是 3.X,我看到的所有示例都是关于为整个测试用例伪造日期时间响应(在测试定义之上使用模拟装饰器)。而我想在测试中途更改该行为,而不是针对整个案例。
有什么建议吗?提前致谢!
好的,我已经深入了解了,想为在 Google 上找到此内容的任何人记录答案;)
1.在 AppEngine 上为 Python 2.7
启用模拟您需要按照说明从 the official docs 复制第三方库(在我们的例子中,"mock")。值得注意的是,在Ubuntu上,建议的命令:
pip install -t lib/ mock
会失败。你会得到这样的错误:
DistutilsOptionError: can't combine user with prefix, exec_prefix/home, or install_(plat)base
这与 Ubuntu 的奇怪冲突有关,该冲突似乎多年来一直未解决,您会看到很多人建议使用 virtualenv 解决方法。我添加了 --system 标志:
pip install --system -t lib/ mock
而且效果很好。请记住按照 appengine_config 的其余说明进行操作,您应该设置好了。 "import mock" 是一个很好的检查方法。
2。模拟 datetime.now() 调用
我的测试模块使用:
from datetime import datetime
在我的测试模块中,导入一些东西:
from mock import patch, Mock
import my_module #Also known as my_module.py
import datetime
那么实际测试用例:
@patch.object(my_module, 'datetime', Mock(wraps=datetime.datetime))
def testThat_myModule_debouncesEmails(self):
fake_time = datetime.datetime.now()
# This is the first time the thing happened. It should send an email.
doSomething()
self.assertEqual(1, emails_sent)
# Five minutes later, the thing happens again. Should be debounced.
fake_time += datetime.timedelta(minutes=5)
my_module.datetime.now.return_value = fake_time
doSomething()
self.assertEqual(1, emails_sent)
# Another 56 minutes pass, the thing happens again. An hour has elapsed, so don't debounce.
fake_time += datetime.timedelta(minutes=56)
my_module.datetime.now.return_value = fake_time
doSomething()
self.assertEqual(2, emails_sent)
# Give it another 15 minutes to check the debouncing kicks back in.
fake_time += datetime.timedelta(minutes=15)
my_module.datetime.now.return_value = fake_time
doSomething()
self.assertEqual(2, emails_sent)
希望这对某人有所帮助!