Last active
February 17, 2021 14:02
-
-
Save niccolomineo/f271f1f0d59911e13969225501aa8e01 to your computer and use it in GitHub Desktop.
Django response mock object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""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