Tengo una función ( foo
) que llama a otra función ( bar
). Si la invocación bar()
genera un HttpError
, quiero manejarlo especialmente si el código de estado es 404; de lo contrario, vuelva a aumentar.
Estoy tratando de escribir algunas pruebas unitarias en torno a esta foo
función, burlándome de la llamada a bar()
. Desafortunadamente, no puedo obtener la llamada simulada bar()
para generar una excepción que es detectada por mi except
bloqueo.
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 de Mock que dicen que debe establecer el side_effect
de una Mock
instancia en una Exception
clase para que la función simulada genere el error.
También miré algunas otras preguntas y respuestas de StackOverflow relacionadas, y parece que estoy haciendo lo mismo que ellos están haciendo para causar una Excepción que se plantee por su simulacro.
- 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é establecer el side_effect
de barMock
no causa que se aumente lo esperado Exception
? Si estoy haciendo algo extraño, ¿cómo debo probar la lógica en mi except
bloque?
fuente
resp.status
código de allí. De dondeHTTPError
vieneHttpError
es una clase definida en el de Googleapiclient
lib que utilizamos en GAE. Está__init__
definido con los parámetros,(resp, content)
por lo que estaba intentando crear una instancia simulada para la respuesta, con el código de estado apropiado especificado.return_value
entonces;resp
no está siendo llamado .HttpError
y en su lugar intenté usar solo unaException
instancia normal . Esto funciona perfectamente. Esto significa que debe tener algo que ver con cómo estoy configurando laHttpError
instancia, probablemente relacionado con cómo estoy creando unaMock
instancia para la respuesta.Respuestas:
Su simulacro está generando la excepción muy bien, pero
error.resp.status
falta el valor. En lugar de usarreturn_value
, solo digaMock
questatus
es un atributo:Los argumentos de palabras clave adicionales
Mock()
se establecen como atributos en el objeto resultante.Puse sus definiciones
foo
ybar
en unmy_tests
módulo, agregado en laHttpError
clase para que yo también pudiera usarlo, y su prueba se puede ejecutar con éxito:Incluso puedes ver la
print '404 - %s' % error.message
línea correr, pero creo que querías usarlaerror.content
allí; ese es elHttpError()
conjunto de atributos del segundo argumento, en cualquier caso.fuente
side_effect
es la parte clave