anr*_*gen 19 python unit-testing mocking
我在python(2.7)中有一个foo方法,如果foo不起作用,在5分钟后放弃.
def keep_trying(self):
timeout = 300 #empirically derived, appropriate timeout
end_time = time.time() + timeout
while (time.time() < end_time):
result = self.foo()
if (result == 'success'):
break
time.sleep(2)
else:
raise MyException('useful msg here')
Run Code Online (Sandbox Code Playgroud)
我知道foo()的一些可能的结果,所以我使用mock来伪造那些返回值.问题是,我不希望测试在看到异常之前运行5分钟.
有没有办法覆盖超时的本地值?我希望这只是几秒钟,以便我可以看到循环尝试几次,然后放弃并加注.
以下不起作用:
@patch.object(myClass.keep_trying, 'timeout')
@patch.object(myClass, 'foo')
def test_keep_trying(self, mock_foo, mock_timeout):
mock_foo.return_value = 'failed'
mock_timeout.return_value = 10 # raises AttributeError
mock_timeout = 10 # raises AttributeError
...
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 17
你不能模拟一个函数的局部变量.为了使代码更容易测试,请将其更改为,例如:
def keep_trying(self, timeout=300):
end_time = time.time() + timeout
# etc, as above
Run Code Online (Sandbox Code Playgroud)
因此,测试以较短的超时运行它变得微不足道!
mgi*_*son 16
而不是试图模拟值,如果timeout,你将要模拟的返回值time.time().
例如
@patch.object(time, 'time')
def test_keep_trying(self, mock_time):
mock_time.side_effect = iter([100, 200, 300, 400, 500, 600, 700, 800])
...
Run Code Online (Sandbox Code Playgroud)
现在第一次time.time()调用时,你将得到100的值,所以它会在你的while循环几圈之后超时.您还可以模拟time.sleep并计算调用它的次数,以确保部分代码正常工作.
另一种方法(与上面的方法不完全正交)是允许用户将可选的timeout关键字传递给函数:
def keep_trying(self, timeout=300):
...
Run Code Online (Sandbox Code Playgroud)
这允许您在测试中指定您想要的任何超时(以及将来不想等待5分钟的代码;-).
| 归档时间: |
|
| 查看次数: |
20435 次 |
| 最近记录: |