У меня есть функция ( 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 документов , которые говорят , что вы должны установить side_effect
из Mock
экземпляра к Exception
классу иметь Передразнивала функцию поднять ошибку.
Я также посмотрел на некоторые другие связанные вопросы и ответы на StackOverflow, и похоже, что я делаю то же самое, что и они, чтобы вызвать и исключить исключение из их макета.
- https://stackoverflow.com/a/10310532/346561
- Как использовать Python Mock для создания исключения - но с заданным значением Errno
Почему установив side_effect
из barMock
не вызывает ожидаемый Exception
быть подняты? Если я делаю что-то странное, как мне протестировать логику в моем except
блоке?
источник
resp.status
код. ОткудаHTTPError
взялось?HttpError
это класс , определенный в Google,apiclient
Lib , который мы используем в GAE. Он__init__
определяется параметрами,(resp, content)
поэтому я пытался создать фиктивный экземпляр для ответа с указанием соответствующего кода состояния.return_value
;resp
не называется .HttpError
а вместо этого попытался использовать только обычныйException
экземпляр. Это прекрасно работает. Это означает, что это должно иметь какое-то отношение к тому, как я настраиваюHttpError
экземпляр, вероятно, связано с тем, как я создаюMock
экземпляр для ответа.Ответы:
Ваш макет просто вызывает исключение, но
error.resp.status
значение отсутствует. Вместо использованияreturn_value
, просто скажите,Mock
чтоstatus
это атрибут:Дополнительные аргументы ключевого слова для
Mock()
устанавливаются как атрибуты результирующего объекта.Я положить ваши
foo
иbar
определения вmy_tests
модуле, добавил вHttpError
классе , так что я мог бы использовать его тоже, и ваше испытание , то может быть побежал к успеху:Вы даже можете увидеть, как
print '404 - %s' % error.message
линия работает, но я думаю, вы хотели использовать ееerror.content
вместо этого;HttpError()
во всяком случае, атрибут устанавливается из второго аргумента.источник
side_effect
является ключевой частью