问题:模拟函数引发异常以测试except块
我有一个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()
我跟着模拟文档这不能不说您应该设置side_effect
一个的Mock
情况下,以一个Exception
班有嘲笑功能引发错误。
我还查看了其他一些与StackOverflow相关的问与答,看起来我在做他们正在做的相同事情,以使他们的模拟引发Exception。
为什么设置side_effect
的barMock
不引起预期Exception
得到提升?如果我做的事情很奇怪,我应该如何在except
块中测试逻辑?
回答 0
您的模拟正在引发异常,但是该error.resp.status
值丢失了。而不是使用return_value
,只是告诉Mock
它status
是一个属性:
barMock.side_effect = HttpError(mock.Mock(status=404), 'not found')
将其他关键字参数Mock()
设置为结果对象的属性。
我将您的foo
和bar
定义放在my_tests
模块中,并添加到HttpError
类中,这样我也可以使用它,然后您的测试可以成功进行:
>>> from my_tests import foo, HttpError
>>> import mock
>>> with mock.patch('my_tests.bar') as barMock:
... barMock.side_effect = HttpError(mock.Mock(status=404), 'not found')
... result = my_test.foo()
...
404 -
>>> result is None
True
您甚至可以看到print '404 - %s' % error.message
生产线运行,但是我想您想在error.content
那里使用它。HttpError()
无论如何,这是第二个参数设置的属性。