I use requests_mock with pytest. I would like to configure a requests_mock object to raise an exception (requests.exceptions.ReadTimeout) a few times and then succeed. How can I do that?
I know how to return various HTTP requests (pass a list to response_list) and how to always raise an exception (using the exc argument) but I don't know how to combine this.
To give some context, I want to test a function that retry on some errors, including requests.exceptions.ReadTimeout, thanks to Tenacity. The goal is to test that the function re-run on a few exceptions and then succeed.
Basically, this is similar to this question but in Python.
To simulate a few timeouts and then a successful response using requests_mock in your pytest test do this:
import requests
import requests_mock
import pytest
def test_retry_then_success():
# Create a mock that raises ReadTimeout twice, then returns success
responses = [
{'exc': requests.exceptions.ReadTimeout}, # 1st call -> timeout
{'exc': requests.exceptions.ReadTimeout}, # 2nd call -> timeout
{'text': 'OK', 'status_code': 200}, # 3rd call -> success
]
with requests_mock.Mocker() as m:
m.get('https://example.com', response_list=responses)
call_count = 0
for _ in range(3):
try:
r = requests.get('https://example.com', timeout=1)
call_count += 1
if r.status_code == 200:
assert r.text == 'OK'
break
except requests.exceptions.ReadTimeout:
call_count += 1
assert call_count == 3
Explanation :
response_list (response-lists documentation) lets you queue multiple mock responses for the same URL.
Each entry can either:
Return a normal HTTP response (text, status_code, etc.)
Or raise an exception using {'exc': <ExceptionType>}
In this example:
The first two requests raise requests.exceptions.ReadTimeout.
The third one returns a successful 200 OK response.
If you’re testing a retry-enabled function (say my_function()), just replace the loop with a single call:
with requests_mock.Mocker() as m:
m.get('https://example.com', response_list=responses)
result = my_function()
assert result == 'OK'
This pattern is the canonical way to simulate intermittent failures and recovery with requests_mock.