英文:
How to generate a fake HTTP request object for unit test in Python?
问题
在Python Django项目中,我们想要编写一个单元测试来向要测试的函数中发送HTTP POST请求。下面的cURL
示例命令显示了我们的测试设置。
cURL
方法从Web服务器的端点开始并触发整个逻辑路径,但我们希望单元测试专注于接受request
参数的特定函数。我们从这篇帖子中获得了提示,其中包含以下用于测试的Python源代码示例来模拟HTTP请求。
我们的问题:
请参阅cURL
命令的-d
参数,我们想知道如何将请求正文传递给伪造的对象。
技术细节:
cURL
命令:
curl http://127.0.0.1:8000/api/transaction/ --insecure \
--verbose \
-d '<env:Envelope ... >
<env:Header>
...
</env:Header>
<env:Body>
...
</env:Body>
</env:Envelope>'
- 用于伪造HTTP请求的Python示例源代码:
from django.core.handlers.wsgi import WSGIRequest
from io import StringIO
from django.contrib.auth.models import AnonymousUser
def GetFakeRequest(path='/', user=None):
"""构造一个伪造的请求(WSGIRequest)对象"""
req = WSGIRequest({
'REQUEST_METHOD': 'GET',
'PATH_INFO': path,
'wsgi.input': StringIO()})
req.user = AnonymousUser() if user is None else user
return req
英文:
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.
Our Question:
See the -d
argument of the cURL
command, we wonder how to feed the request body in the faked object.
Technical Details:
- The
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>
'
- The Python sample source code for faking a HTTP request:
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
答案1
得分: 1
下面是您要翻译的内容:
也许一个替代方法是使用 RequestFactory
来构建 request
对象。然后使用类似参数的方式调用该函数。类似这样:
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):
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="john_doe@test.com", 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"
我将其放在了视图内,但当然您可以将其放在任何您想要的地方。
英文:
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="john_doe@test.com", 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论