una - try except python 3
Simulando una función para generar una excepción para probar un bloque excepto (1)
Su simulación está generando la excepción muy bien, pero
error.resp.status
valor
error.resp.status
.
En lugar de usar
return_value
, solo dígale a
Mock
que el
status
es un atributo:
barMock.side_effect = HttpError(mock.Mock(status=404), ''not found'')
Los argumentos de palabras clave adicionales para
Mock()
se establecen como atributos en el objeto resultante.
Puse tus definiciones
foo
y
bar
en un módulo
my_tests
, agregado en la
clase
HttpError
para poder usarlo también, y tu prueba se puede ejecutar con éxito:
>>> 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
Incluso puede ver la línea
print ''404 - %s'' % error.message
run, pero creo que quería usar
error.content
allí en su lugar;
ese es el atributo que
HttpError()
establece a partir del segundo argumento, en cualquier caso.
Tengo una función (
foo
) que llama a otra función (
bar
).
Si invocar
bar()
genera un
HttpError
, quiero manejarlo especialmente si el código de estado es 404; de lo contrario, vuelva a subir.
Estoy tratando de escribir algunas pruebas unitarias alrededor de esta función
foo
, burlándome de la llamada a
bar()
.
Desafortunadamente, no puedo obtener la llamada burlada a
bar()
para generar una Excepción que es capturada por mi bloque
except
.
Aquí está mi código que ilustra mi problema:
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()
Seguí los
documentos
side_effect
que dicen que debe establecer el efecto
side_effect
de una instancia
Mock
en una clase de
Exception
para que la función
Mock
side_effect
el error.
También miré algunas otras preguntas y respuestas relacionadas con StackOverflow, y parece que estoy haciendo lo mismo que están haciendo para provocar y que su simulación provoque Excepción.
- https://stackoverflow.com/a/10310532/346561
- Cómo usar Python Mock para generar una excepción, pero con Errno establecido en un valor dado
¿Por qué configurar el efecto
side_effect
de
barMock
no provoca que se
barMock
la
Exception
esperada?
Si estoy haciendo algo extraño, ¿cómo debo hacer para probar la lógica en mi bloque
except
?