In a Python Django project, we want a unit test to feed a HTTP POST request into the function under test. The cURL sample command below shows our test settings.
The cURL approach starts from the web server's endpoint and triggers the entire logic path, but we want the unit test to focus on a specific function taking in the request argument. And, we got hint from this post with the below sample Python source code to fake a HTTP request for testing.
See the -d argument of the cURL command, we wonder how to feed the request body in the faked object.
cURL command:curl http://127.0.0.1:8000/api/transaction/ --insecure \
--verbose \
-d '<env:Envelope ... >
<env:Header>
...
</env:Header>
<env:Body>
...
</env:Body>
</env:Envelope>
'
from django.core.handlers.wsgi import WSGIRequest
from io import StringIO
from django.contrib.auth.models import AnonymousUser
def GetFakeRequest(path='/', user=None):
""" Construct a fake request(WSGIRequest) object"""
req = WSGIRequest({
'REQUEST_METHOD': 'GET',
'PATH_INFO': path,
'wsgi.input': StringIO()})
req.user = AnonymousUser() if user is None else user
return req
Maybe an alternative is to build the request object using RequestFactory. And call the the function using such as param. Something like:
tests.py
from django.test import TestCase, RequestFactory
from django.contrib.auth import get_user_model
from myapp.views import my_function
class TestHTTPRequest(TestCase):
def setUp(self) -> None:
self.data = "<env:Envelope ... > \
<env:Header> \
... \
</env:Header> \
<env:Body> \
... \
</env:Body> \
</env:Envelope>"
self.factory = RequestFactory()
self.user = get_user_model().objects.create_user(
username="john", email="[email protected]", password="top_secret"
)
def test_some_function(self):
request = self.factory.get("some/url/", data={'data': self.data})
request.user = self.user
response = my_function(request)
self.assertEqual(response, "Some way to confirm success")
views.py
def my_function(request):
data = request.GET.get('data')
# print(f'The data: \n {data}')
# print(request.user.email)
return "Some way to confirm success"
I placed it inside views, but of course it can be anywhere you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With