我在扭曲的试验单元测试中遇到麻烦。被测试的函数返回一个延迟,我返回从单元测试中推迟的。但是,似乎我已经应用的补丁一旦返回延迟就会被还原,它不会等到延迟解决后。
请参阅以下示例:
schedule.py
import time
from twisted.internet import task, reactor
class Schedule():
def get_time(self):
t = time.time()
return task.deferLater(reactor, 2, lambda: t)
def get_time_future(self):
return task.deferLater(reactor, 2, lambda: time.time())
schedule_test.py
import mock
from twisted.trial import unittest
from schedule import Schedule
class ScheduleTest(unittest.TestCase):
@mock.patch('schedule.time')
def test_get_time(self, mock_time):
mock_time.time.return_value = 1450407660
d = Schedule().get_time()
d.addCallback(self.assertEqual, 1450407660)
return d
@mock.patch('schedule.time')
def test_get_time_future(self, mock_time):
mock_time.time.return_value = 1450407660
d = Schedule().get_time_future()
d.addCallback(self.assertEqual, 1450407660)
return d
输出
test_schedule
ScheduleTest
test_get_time ... [OK]
test_get_time_future ... [FAIL]
===============================================================================
[FAIL]
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/twisted/trial/_synctest.py", line 437, in assertEqual
super(_Assertions, self).assertEqual(first, second, msg)
File "/usr/lib/python2.7/unittest/case.py", line 515, in assertEqual
assertion_func(first, second, msg=msg)
File "/usr/lib/python2.7/unittest/case.py", line 508, in _baseAssertEqual
raise self.failureException(msg)
twisted.trial.unittest.FailTest: 1456370638.190432 != 1450407660
test_schedule.ScheduleTest.test_get_time_future
-------------------------------------------------------------------------------
Ran 2 tests in 4.024s
FAILED (failures=1, successes=1)
在上面的例子中我嘲笑time
的方式有什么问题吗?
答案 0 :(得分:4)
你嘲笑time
的方式确实有问题。 mock
装饰器在输入测试函数时设置补丁,然后在退出时删除它们。但是,您返回Deferred
,这意味着在测试函数退出后,time.time
回调运行良好。
如果您只想继续使用类似于模拟的修补界面,可以使用Twisted' TestCase.patch
,我认为这会考虑Deferreds
。
但是,mocking is a testing anti-pattern以及处理时间流逝的更好方法是使用the documented API for testing the passage of time,twisted.internet.task.Clock
。
答案 1 :(得分:1)
正如Glyph指出的那样,使用TestCase.patch
可以提供帮助。补丁需要按如下所示执行:
def test_get_time_future(self):
mock_time = MagicMock()
mock_time.time.return_value = 1450407660
self.patch(sys.modules['schedule'], 'time', mock_time)
d = Schedule().get_time_future()
d.addCallback(self.assertEqual, 1450407660)
return d
此测试通过。