【发布时间】:2015-04-03 00:46:18
【问题描述】:
我有一个函数 (foo),它调用另一个函数 (bar)。如果调用bar()引发HttpError,如果状态码为404我想特别处理,否则重新引发。
我正在尝试围绕这个foo 函数编写一些单元测试,模拟对bar() 的调用。不幸的是,我无法获得对bar() 的模拟调用来引发我的except 块捕获的异常。
这是说明我的问题的代码:
import unittest
import mock
from apiclient.errors import HttpError
class FooTests(unittest.TestCase):
@mock.patch('my_tests.bar')
def test_foo_shouldReturnResultOfBar_whenBarSucceeds(self, barMock):
barMock.return_value = True
result = foo()
self.assertTrue(result) # passes
@mock.patch('my_tests.bar')
def test_foo_shouldReturnNone_whenBarRaiseHttpError404(self, barMock):
barMock.side_effect = HttpError(mock.Mock(return_value={'status': 404}), 'not found')
result = foo()
self.assertIsNone(result) # fails, test raises HttpError
@mock.patch('my_tests.bar')
def test_foo_shouldRaiseHttpError_whenBarRaiseHttpErrorNot404(self, barMock):
barMock.side_effect = HttpError(mock.Mock(return_value={'status': 500}), 'error')
with self.assertRaises(HttpError): # passes
foo()
def foo():
try:
result = bar()
return result
except HttpError as error:
if error.resp.status == 404:
print '404 - %s' % error.message
return None
raise
def bar():
raise NotImplementedError()
我遵循了Mock docs,它说您应该将Mock 实例的side_effect 设置为Exception 类,以使模拟函数引发错误。
我还查看了一些其他相关的 StackOverflow 问答,看起来我正在做与他们正在做的相同的事情,以导致他们的模拟引发异常。
- https://stackoverflow.com/a/10310532/346561
- How to use Python Mock to raise an exception - but with Errno set to a given value
为什么设置barMock 的side_effect 不会导致预期的Exception 被提升?如果我在做一些奇怪的事情,我应该如何在 except 块中测试逻辑?
【问题讨论】:
-
我很确定您的异常 is 正在引发,但我不确定您如何在那里设置
resp.status代码。HTTPError来自哪里? -
@MartijnPieters
HttpError是我们在 GAE 中使用的 Google'sapiclientlib 中定义的类。它的__init__是用参数(resp, content)定义的,所以我试图为响应创建一个模拟实例,并指定适当的状态代码。 -
对,原来是this class;但是您不需要用户
return_value;resp未被调用。 -
我在没有使用
HttpError的情况下再次尝试了我的代码,而是尝试使用常规的Exception实例。这完美地工作。这意味着它必须与我如何配置HttpError实例有关,可能与我如何为响应创建Mock实例有关。
标签: python unit-testing python-2.7 mocking python-mock