Ich habe eine Funktion ( foo
), die eine andere Funktion ( bar
) aufruft . Wenn das Aufrufen bar()
eines ausgelöst wird HttpError
, möchte ich es speziell behandeln, wenn der Statuscode 404 lautet, andernfalls erneut erhöhen.
Ich versuche, einige Unit-Tests um diese foo
Funktion herum zu schreiben und den Aufruf von zu verspotten bar()
. Leider kann ich den verspotteten Anruf nicht erhalten bar()
, um eine Ausnahme auszulösen, die von meinem except
Block erfasst wird.
Hier ist mein Code, der mein Problem veranschaulicht:
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()
Ich folgte den Mock docs , die sagen , dass Sie die eingestellte sollte side_effect
eine Mock
Instanz in eine Exception
Klasse , um die verspottete Funktion erhöhen , den Fehler zu haben.
Ich habe mir auch einige andere verwandte Fragen und Antworten zu StackOverflow angesehen, und es sieht so aus, als würde ich das Gleiche tun, um zu bewirken, dass die Ausnahme durch ihren Schein ausgelöst wird.
- https://stackoverflow.com/a/10310532/346561
- Verwendung von Python Mock zum Auslösen einer Ausnahme - wobei Errno jedoch auf einen bestimmten Wert festgelegt ist
Warum setzt die side_effect
von barMock
nicht der erwartete verursacht Exception
erhöht werden? Wenn ich etwas Seltsames mache, wie soll ich dann die Logik in meinem except
Block testen ?
quelle
resp.status
Code gibt. Woher kommtHTTPError
das?HttpError
ist eine Klasse , in definierten Googleapiclient
lib , die wir in GAE verwenden. Es__init__
wird mit den Parametern definiert,(resp, content)
daher habe ich versucht, eine Scheininstanz für die Antwort mit dem entsprechenden angegebenen Statuscode zu erstellen.return_value
;resp
wird nicht aufgerufen .HttpError
versucht und stattdessen nur eine reguläreException
Instanz verwendet. Das funktioniert perfekt. Dies bedeutet, dass es etwas damit zu tun haben muss, wie ich dieHttpError
Instanz konfiguriere , wahrscheinlich im Zusammenhang damit, wie ich eineMock
Instanz für die Antwort erstelle .Antworten:
Ihr Mock löst die Ausnahme ein, aber der
error.resp.status
Wert fehlt. Anstatt Gebrauchreturn_value
, nur sagen ,Mock
dassstatus
ein Attribut:Zusätzliche Schlüsselwortargumente,
Mock()
die als Attribute für das resultierende Objekt festgelegt werden sollen.Ich habe Ihre
foo
undbar
Definitionen in einmy_tests
Modul eingefügt, das im hinzugefügt wurdeHttpError
Klasse , damit ich es auch verwenden kann, und Ihr Test kann dann erfolgreich ausgeführt werden:Sie können sogar sehen, wie die
print '404 - %s' % error.message
Linie läuft, aber ich denke, Sie wollten sieerror.content
stattdessen dort verwenden. das sindHttpError()
jedenfalls die Attributmengen aus dem zweiten Argument.quelle
side_effect
ist der Schlüssel