我有一个叫做 foo
的函数,它调用了另一个函数 bar
。如果调用 bar()
引发了 HttpError
异常,并且 HTTP 响应状态码为 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文档所说的设置Mock
实例的side_effect
为Exception
类,以使模拟函数引发错误。
我还查看了一些其他相关的StackOverflow Q&As,并且看起来我正在做他们用来引发mock异常的相同操作。
为什么设置barMock
的side_effect
没有引发预期的Exception
?如果我做了一些奇怪的东西,那么该如何测试except
块中的逻辑?
resp.status
代码的。HTTPError
是从哪里来的? - Martijn PietersHttpError
是在Google的apiclient
库中定义的一个类,我们在GAE中使用它。它的__init__
是用参数(resp, content)
定义的,因此我试图为响应创建一个模拟实例,并指定适当的状态代码。 - Jesse Webbreturn_value
;因为resp
没有被调用。 - Martijn PietersHttpError
,而是使用普通的Exception
实例。这样做完美地解决了问题。这意味着问题肯定与我配置HttpError
实例有关,可能与我为响应创建Mock
实例的方式有关。 - Jesse Webb