Ich habe eine Funktion (foo
), die eine andere Funktion aufruft (bar
). Wenn bar()
ausgelöst wird, wird ein HttpError
ausgelöst, ich möchte es speziell behandeln, wenn der Statuscode 404 ist, andernfalls re-raise.Verspotten einer Funktion zum Auslösen einer Ausnahme zum Testen eines Ausnahmeblocks
Ich versuche einige Komponententests um diese foo
Funktion zu schreiben, die den Anruf zu bar()
spotten. Leider bin ich nicht in der Lage, den verspotteten Anruf an bar()
zu bekommen, um eine Ausnahme auszulösen, die von meinem except
Block gefangen wird.
Hier ist mein Code, der mein Problem zeigt:
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 die Mock docs gefolgt, die sagen, dass Sie die side_effect
einer Mock
-Instanz in eine Exception
Klasse gesetzt sollte die verspottete Funktion erhöhen, den Fehler zu haben.
Ich schaute auch auf einige andere verwandte StackOverflow Q & As, und es sieht aus wie ich mache das gleiche, was sie tun, um zu verursachen und Exception von ihrem Schein erhoben werden.
- https://stackoverflow.com/a/10310532/346561
- How to use Python Mock to raise an exception - but with Errno set to a given value
Warum Setzen der side_effect
von barMock
nicht den erwarteten Exception
verursacht erhöht werden? Wenn ich etwas Seltsames mache, wie soll ich in meinem except
Block Logik testen?
Ich bin mir ziemlich sicher, dass Ihre Exception * ausgelöst wird, aber ich bin mir nicht sicher, wie Sie den 'resp.status'-Code dort einstellen. Woher kommt 'HTTPError'? –
@MartijnPieters 'HttpError' ist eine Klasse, die in [Googles' apiclient' lib] (https://developers.google.com/api-client-library/python/) definiert ist, die wir in GAE verwenden. Es ist '__init__' mit den Parametern' (resp, content) 'definiert, also habe ich versucht, eine Mock-Instanz für die Antwort zu erstellen, mit dem entsprechenden Status-Code angegeben. –
Richtig, also ist es [diese Klasse] (https://github.com/google/google-api-python-client/blob/master/googleapiclient/errors.py#L35-L63); aber Sie müssen dann 'return_value' nicht verwenden; 'resp' wird nicht * genannt *. –