Django REST Framework - 在 ApiClient 的序列化程序测试中设置请求
Django REST Framework - Set request in serializer test for ApiClient
我已经阅读:。它对我不起作用!因为我使用的是 APIClient 而不是他那样的 RequestFactory。
我构建了一个 Web 应用程序,其中后端是使用 Django REST Framework 实现的。现在我正在编写单元测试,并且在测试我的序列化程序方法时遇到了问题。这是我正在努力使用的序列化程序方法的一个示例:
def get_can_edit(self, obj):
request = self.context['request']
user = User.objects.get(username=request.user)
return user == obj.admin
当试图从测试中调用它时,首先我声明了一个序列化程序的实例:
但现在我需要 self.serializer 才能在 get_can_edit 执行 self.context.get('request') 时获得正确的请求。我使用 APIClient 创建了一个包含正确信息的虚假请求:
self.client = APIClient()
self.client.force_authenticate(user)
conference = a_fake_conference
res = self.client.get('conference:conference-detail'. args=[conference.id])
serializer = ConferenceSerializer(conference, context={WHAT_IS_REQUEST?})
# I'm using a dict as context but the request gave me an error: context={'request': { 'user': user }}
sert.assertEqual(res.data, serializer.data)
现在我卡住了,因为我不确定如何将 request1 添加到序列化程序,这样 request = self.context['request']
将 return
谢谢。
使用wsgi_request
(source code-Django) of APIClient
获取WSGI请求对象
self.client = APIClient()
self.client.force_authenticate(user)
res = self.client.get('conference:conference-detail'. args=[conference.id]
# make sure to call the `get(...)` method before accessing `wsgi_request` attribute
<b>request_object = res.wsgi_request</b>
免责声明:不确定这是否是获取 request
对象的 DRF 方式。
你在这里相互测试两件事,所以这是问题的一部分。通常,您会将 self.client.get(...)
用作 集成测试 ,即确保从请求到响应的所有内容都按预期工作的测试。对于像这样的测试,您不会使用序列化器,因为那时您正在使用您的应用程序代码(您的序列化器)来测试自身。
如果您正在编写集成测试,则应该使用类似以下内容来测试原始响应:
from django.test import TestCase, RequestFactory
class MyUnitTestCase(TestCase):
def test_the_whole_stack(self):
response = self.client.get(
"conference:conference-detail", args=[conference.id]
)
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.json()["some-key-you-expect"],
"Some value you expect"
)
请注意,您也不必直接调用 APIClient()。它默认存在。
对于单元测试,例如您为确保序列化程序正常工作而编写的那种测试,您不需要或不想使用 WSGIRequest 对象。相反,Django 为这种情况提供了一个 RequestFactory:
from django.test import TestCase, RequestFactory
class MyUnitTestCase(TestCase):
def test_my_serialiser(self):
serializer = ConferenceSerializer(
conference,
context={"request": RequestFactory().get("/")}
)
self.assertEqual(
serialiser.data["some-key-you-expect"],
"Some value you expect"
)
我已经阅读:
我构建了一个 Web 应用程序,其中后端是使用 Django REST Framework 实现的。现在我正在编写单元测试,并且在测试我的序列化程序方法时遇到了问题。这是我正在努力使用的序列化程序方法的一个示例:
def get_can_edit(self, obj):
request = self.context['request']
user = User.objects.get(username=request.user)
return user == obj.admin
当试图从测试中调用它时,首先我声明了一个序列化程序的实例:
但现在我需要 self.serializer 才能在 get_can_edit 执行 self.context.get('request') 时获得正确的请求。我使用 APIClient 创建了一个包含正确信息的虚假请求:
self.client = APIClient()
self.client.force_authenticate(user)
conference = a_fake_conference
res = self.client.get('conference:conference-detail'. args=[conference.id])
serializer = ConferenceSerializer(conference, context={WHAT_IS_REQUEST?})
# I'm using a dict as context but the request gave me an error: context={'request': { 'user': user }}
sert.assertEqual(res.data, serializer.data)
现在我卡住了,因为我不确定如何将 request1 添加到序列化程序,这样 request = self.context['request']
将 return
谢谢。
使用wsgi_request
(source code-Django) of APIClient
获取WSGI请求对象
self.client = APIClient()
self.client.force_authenticate(user)
res = self.client.get('conference:conference-detail'. args=[conference.id]
# make sure to call the `get(...)` method before accessing `wsgi_request` attribute
<b>request_object = res.wsgi_request</b>
免责声明:不确定这是否是获取 request
对象的 DRF 方式。
你在这里相互测试两件事,所以这是问题的一部分。通常,您会将 self.client.get(...)
用作 集成测试 ,即确保从请求到响应的所有内容都按预期工作的测试。对于像这样的测试,您不会使用序列化器,因为那时您正在使用您的应用程序代码(您的序列化器)来测试自身。
如果您正在编写集成测试,则应该使用类似以下内容来测试原始响应:
from django.test import TestCase, RequestFactory
class MyUnitTestCase(TestCase):
def test_the_whole_stack(self):
response = self.client.get(
"conference:conference-detail", args=[conference.id]
)
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.json()["some-key-you-expect"],
"Some value you expect"
)
请注意,您也不必直接调用 APIClient()。它默认存在。
对于单元测试,例如您为确保序列化程序正常工作而编写的那种测试,您不需要或不想使用 WSGIRequest 对象。相反,Django 为这种情况提供了一个 RequestFactory:
from django.test import TestCase, RequestFactory
class MyUnitTestCase(TestCase):
def test_my_serialiser(self):
serializer = ConferenceSerializer(
conference,
context={"request": RequestFactory().get("/")}
)
self.assertEqual(
serialiser.data["some-key-you-expect"],
"Some value you expect"
)