How do I simulate connection errors and request timeouts in python unit tests
13,143
Untested code but...
def connection_error():
raise requests.exceptions.ConnectionError
class TestSuitabilityFunctions(TestCase):
@patch.object(module_that_youre_testing, "requests")
def test_connection_error(self, mock_requests):
mock_requests.get = MagicMock(side_effect=connection_error)
with self.assertRaises(requests.exceptions.ConnectionError) as cm:
resp = call_the_api()
exception = cm.exception
self.assertEqual(resp, {'request_error': 'ConnectionTimeout'})
... or similar should do the trick. Off the top of my head I can't remember how assertRaises interacts with errors that are caught. Maybe you don't even need the assertRaises part.
Related videos on Youtube
Author by
Tom
My name is Tom and I am a Computer Science major at Wentworth Institute of Technology. Find out more at http://tomleo.com
Updated on June 07, 2022Comments
-
Tom almost 2 years
Suppose my django/flask application pulls in information from API's, how can I test that connection exceptions are caught and handled properly?
So for example here is a function that calls an API:
import requests def call_the_api(): url = 'http://httpbin.org/get' try: req = requests.get(url) if req.json().get('errors'): logger.warn("API error response") return {'request_error': 'api_error_response'} except requests.exceptions.ConnectionError: logger.warn('ConnectionError') return {'request_error': 'ConnectionTimeout'} except requests.exception.Timeout: logger.warn('API request timed out') return {'request_error': 'Timeout'} except Exception, ex: logger.warn("API request Exception: %s", ex) return {'request_error': ex} else: return req.json()
For testing responses from the API I found mock to be very useful.
def mock_get_request(): response = requests.get.return_value json_file = 'sample_response.json' json_file_path = os.path.join(os.path.dirname(__file__), json_file) with open(json_file_path, 'r') as f: response.content = response.text = f.read() response.status_code = 200 response.encoding = 'utf-8' response.json = lambda: json.loads(response.content.decode(response.encoding)) response.url = u'%s' % args[0] return response class TestSuitabilityFunctions(TestCase): def test_call_the_api(self): requests.get = MagicMock(side_effect=mock_get_request) resp = call_the_api() self.assertEqual(resp.get('url'), "http://httpbin.org/get")
So my question is how would I go about simulating a connection timeout or error?
-
digitaldavenyc over 6 yearsThis is a bad approach because it isn't properly mocking the request library, a decorator should be used so it doesn't mock requests outside of a single test.
-
Bheid almost 2 years@digitaldavenyc could you please provide the right way to do it?