我正在尝试测试一些反跳逻辑-这些是我使用2.7运行时环境为Google App Engine网络应用程序运行的本地单元测试。我所有其他的测试都进行得很好,但是这个让我很沮丧!
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()发送电子邮件的时间,然后在以后的所有尝试中重新运行datetime.now(),如果不到一个小时就返回了。
有两件事出了错:
我认为unittest库仅在3.X中添加了模拟支持,并且我不希望更新我的整个应用程序。
即使我使用的是3.X,我看到的所有示例也都涉及伪造整个测试用例的日期时间响应(使用测试定义上方的模拟装饰器)。而我想在测试中途更改行为,而不是整个案例。
有什么提示吗?预先感谢!
答案 0 :(得分:0)
好的,我想深入了解它,并希望为在Google上找到答案的人提供答案;)
1。在适用于Python 2.7的AppEngine上启用模拟功能
您需要按照说明从the official docs复制第三方库(在我们的示例中为“模拟”)。值得注意的是,在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的其余说明进行操作,并且应该已设置好。 “导入模拟”是检查的好方法。
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)
希望这对某人有帮助!