Издевательство над функцией для создания исключения для проверки блока except
у меня есть функция (foo
), которая вызывает другую функцию (bar
). При вызове bar()
выдает HttpError
, Я хочу обрабатывать его специально, если код состояния 404, в противном случае повторно поднять.
я пытаюсь написать юнит-тестов по этой foo
функция, издеваясь над вызовом bar()
. К сожалению, я не могу получить издевательский звонок bar()
чтобы вызвать исключение, которое поймано my 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 которые говорят, что вы должны установить side_effect
на Mock
экземпляр Exception
класс, чтобы издевательская функция вызывала ошибку.
я также посмотрел на некоторые другие связанные с StackOverflow Q&As, и похоже, что я делаю то же самое, что они делают, чтобы вызвать и исключение, которое будет поднято их макетом.
- https://stackoverflow.com/a/10310532/346561
- как чтобы использовать Python Mock для создания исключения - но с Errno, установленным в заданное значение
почему задание side_effect
на barMock
не вызывая ожидаемого Exception
быть воспитанным? Если я делаю что-то странное, как я должен идти о тестировании логики в моем except
заблокировать?
1 ответ:
ваш макет поднимает исключение просто отлично, но
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
line run, но я думаю, что вы хотели использоватьerror.content
там вместо этого; это атрибутHttpError()
устанавливает из второго аргумента, во всяком случае.