Skip to content

Instantly share code, notes, and snippets.

@therightstuff
Last active May 31, 2023 08:34
Show Gist options
  • Save therightstuff/99b1832861628597da47a01e4791038e to your computer and use it in GitHub Desktop.
Save therightstuff/99b1832861628597da47a01e4791038e to your computer and use it in GitHub Desktop.
Simple request mocking with requests_mock
def setup_mocker(mocker, expected_requests):
"""Note: this requires the exact number of expected requests.
expected_requests is an array in the following format:
[
{
"url": "https://www.example.com",
"method": "GET",
"exc": requests.exceptions.ConnectTimeout, # will override "status_code" and "json"
"status_code": 404, # defaults to 200
"response_body": # dictionary object, optional
},
...
]
"""
# group the requests by method and url
mock_requests = {}
for request in expected_requests:
if request["method"] not in ["GET", "POST"]:
raise Exception(f"Unsupported method: {request['method']}")
if request["method"] not in mock_requests.keys():
mock_requests[request["method"]] = {}
if request["url"] not in mock_requests[request["method"]].keys():
mock_requests[request["method"]][request["url"]] = []
if "exc" in request.keys() and request["exc"] is not None:
response = {
"exc": request["exc"],
}
else:
response = {
"status_code": request["status_code"] if "status_code" in request.keys() else 200,
}
if "response_body" in request.keys():
response["json"] = request["response_body"]
mock_requests[request["method"]][request["url"]].append(response)
if "GET" in mock_requests.keys():
for url in mock_requests["GET"]:
mocker.get(url, mock_requests["GET"][url])
if "POST" in mock_requests.keys():
for url in mock_requests["POST"]:
mocker.post(url, mock_requests["POST"][url])
from http import HTTPStatus
import json
import pytest
import requests
import requests_mock
from requests_mocking import setup_mocker
def test_example():
expected_requests = [
{
"url": "https://www.example.com/hello",
"method": "GET",
"response_body": {"hello": "world"},
},
{
"url": "https://www.example.com/send",
"method": "POST",
"response_body": {"message": "Accepted."},
},
{
"url": "https://www.example.com/timeout",
"method": "POST",
"exc": requests.exceptions.ConnectTimeout,
},
{
"url": "https://www.example.com/same_request_different_result",
"method": "GET",
"response_body": {"attempt": 1},
},
{
"url": "https://www.example.com/same_request_different_result",
"method": "GET",
"status_code": 404,
"response_body": {"attempt": 2},
},
]
with requests_mock.Mocker() as mocker:
setup_mocker(mocker, expected_requests)
print("Testing GET /hello ...")
response = requests.get("https://www.example.com/hello")
assert int(response.status_code) == int(HTTPStatus.OK)
assert response.json() == {"hello": "world"}
print("Testing POST /send ...")
response = requests.post("https://www.example.com/send")
assert int(response.status_code) == int(HTTPStatus.OK)
assert response.json() == {"message": "Accepted."}
print("Testing POST /timeout ...")
with pytest.raises(requests.exceptions.ConnectTimeout):
response = requests.post("https://www.example.com/timeout")
print("Testing GET /same_request_different_result ...")
response = requests.get("https://www.example.com/same_request_different_result")
assert int(response.status_code) == int(HTTPStatus.OK)
assert response.json() == {"attempt": 1}
print("Testing GET /same_request_different_result ...")
response = requests.get("https://www.example.com/same_request_different_result")
assert int(response.status_code) == int(HTTPStatus.NOT_FOUND)
assert response.json() == {"attempt": 2}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment