Skip to content

Instantly share code, notes, and snippets.

@niccolomineo
Last active February 17, 2021 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niccolomineo/f271f1f0d59911e13969225501aa8e01 to your computer and use it in GitHub Desktop.
Save niccolomineo/f271f1f0d59911e13969225501aa8e01 to your computer and use it in GitHub Desktop.
Django response mock object
"""Define Django Response Mock."""
import json
from django.conf import settings
from django.utils.translation import gettext_lazy as _
class ResponseMock:
"""Define response mock."""
requests = None
def __init__(self, method, url, **kwargs):
"""Override initialisation."""
if self.requests is None:
raise SystemExit(_("Did you forget to pass a list of requests?"))
requests_left = len(self.requests)
for request in self.requests:
if (
self._uri_matches(request, url)
and self._method_matches(request, method)
and self._payloads_match(kwargs, request)
):
self.text = self._get_mock_data(request)
self.status_code = request["status_code"]
self.method = request["method"]
self.headers = kwargs.get("headers", {})
break
else:
requests_left = requests_left - 1
if not requests_left:
raise SystemExit(
_(
f"Check your '{method.upper()}' mock for '{url}', "
f"with payload {str(kwargs)}"
)
)
def _is_valid_path(self, value):
"""Check whether value is valid path."""
return type(value) in (str, tuple)
def _get_mock_data(self, request):
"""Return mock data from file."""
if self._is_valid_path(request["return_value"]):
data_filepath = f'{settings.BASE_DIR}/{request["return_value"]}'
try:
with open(data_filepath) as file_data:
data = json.load(file_data)
except FileNotFoundError as e:
raise SystemExit(e)
else:
data = request["return_value"]
return json.dumps(data)
def _payloads_match(self, kwargs, request):
"""Check whether payload matches."""
payload_attrs = ("json", "data")
for attr in payload_attrs:
payload_exists = attr in request and attr in kwargs
payload_differs = payload_exists and request[attr] != kwargs[attr]
if payload_differs:
return False
return True
def _method_matches(self, request, method):
"""Check whether HTTP method matches."""
return request["method"] == method.upper()
def _uri_matches(self, request, url):
"""Check whether URI matches."""
return "uri" in request and url.endswith(request["uri"])
def raise_for_status(self):
"""Override raising exception for status."""
pass
def json(self):
"""Override json loader."""
return json.loads(self.text)
"""Define response mock tests."""
from django.test import SimpleTestCase
from response_mock import ResponseMock
class TestResponseMock(SimpleTestCase):
"""Define response mock tests."""
def test_response_mock_success(self):
"""Test successfully mocking the url."""
ResponseMock.requests = [
{
"uri": "my/endpoint/1",
"method": "GET",
"status_code": 200,
"return_value": {},
}
]
self.assertTrue(ResponseMock("GET", "dummyhost/api/v1/my/endpoint/1"))
def test_response_mock_fail_endpoint_list_empty(self):
"""Test failing to perform mocking due to requests list being empty."""
with self.assertRaises(SystemExit):
ResponseMock("GET", "dummyhost/api/v1/my/endpoint/3")
def test_response_mock_fail_url_not_mocked(self):
"""Test failing to mock the following available url."""
ResponseMock.requests = ["my/endpoint/1", "my/endpoint/2"]
with self.assertRaises(SystemExit):
ResponseMock("GET", "dummyhost/api/v1/my/endpoint/3")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment