我正在编写端点以使用Django Rest Framework 3接收和解析here。为了匹配有效负载规范,我正在编写有效负载请求工厂并测试它&#39} ; s生成有效请求。
然而,当尝试测试使用DRF的APIRequestFactory
类生成的请求时,会出现问题。这是我能提出的最小的失败测试 - 问题是DRF Request
生成的请求似乎无法通过DRF from rest_framework.request import Request
from rest_framework.parsers import JSONParser
from rest_framework.test import APIRequestFactory, APITestCase
class TestRoundtrip(APITestCase):
def test_round_trip(self):
"""
A DRF Request can be loaded into a DRF Request object
"""
request_factory = APIRequestFactory()
request = request_factory.post(
'/',
data={'hello': 'world'},
format='json',
)
result = Request(request, parsers=(JSONParser,))
self.assertEqual(result.data['hello'], 'world')
类解析。这是预期的行为吗?
E
======================================================================
ERROR: A DRF Request can be loaded into a DRF Request object
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 380, in __getattribute__
return getattr(self._request, attr)
AttributeError: 'WSGIRequest' object has no attribute 'data'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/james/active/prlint/prlint/github/tests/test_payload_factories/test_roundtrip.py", line 22, in test_round_trip
self.assertEqual(result.data['hello'], 'world')
File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 382, in __getattribute__
six.reraise(info[0], info[1], info[2].tb_next)
File "/home/james/active/prlint/venv/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 186, in data
self._load_data_and_files()
File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 246, in _load_data_and_files
self._data, self._files = self._parse()
File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 312, in _parse
parsed = parser.parse(stream, media_type, self.parser_context)
File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/parsers.py", line 64, in parse
data = stream.read().decode(encoding)
AttributeError: 'str' object has no attribute 'read'
----------------------------------------------------------------------
堆栈跟踪是:
Request
我显然做了一些愚蠢的事情 - 我已经弄乱了编码...意识到我需要将解析器列表传递给UnsupportedMediaType
以避免APIRequestFactory
错误,现在我被困在这里。
我应该做些不同的事吗?也许避免使用X-GitHub-Event
?或者以不同的方式测试我构建的GitHub请求?
GitHub向具有def PayloadRequestFactory():
"""
Build a Request, configure it to look like a webhook payload from GitHub.
"""
request_factory = APIRequestFactory()
request = request_factory.post(url, data=PingPayloadFactory())
request.META['HTTP_X_GITHUB_EVENT'] = 'ping'
return request
标头的已注册webhook发送请求,因此为了测试我的webhook DRF代码,我需要能够在测试时模拟此标头。
我成功的道路是构建自定义请求并使用工厂将负载加载到其中。这是我的工厂代码:
PayloadRequestFactory
问题已经出现,因为我想断言Request
正在为各种传递的参数生成有效请求 - 所以我试图解析它们并断言它们的有效性但是DRF的{{1}类似乎无法实现这一点 - 因此我的问题是测试失败。
所以我真正的问题是 - 我应该如何测试PayloadRequestFactory
是否产生了我需要的那种请求?
答案 0 :(得分:1)
"哟dawg,我听说你喜欢Request,cos'你把一个请求放在一个请求中#34; XD
我这样做:
from rest_framework.test import APIClient
client = APIClient()
response = client.post('/', {'github': 'payload'}, format='json')
self.assertEqual(response.data, {'github': 'payload'})
# ...or assert something was called, etc.
希望这有帮助
答案 1 :(得分:1)
查看tests for APIRequestFactory
in
DRF,stub
views
创建然后运行该视图 - 检查输出以获得预期结果。
因此,合理但稍长的解决方案是将此策略复制到
在此之前断言PayloadRequestFactory
正在构建有效请求
指向一个完整的视图。
上述测试成为:
from django.conf.urls import url
from django.test import TestCase, override_settings
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.test import APIRequestFactory
@api_view(['POST'])
def view(request):
"""
Testing stub view to return Request's data and GitHub event header.
"""
return Response({
'header_github_event': request.META.get('HTTP_X_GITHUB_EVENT', ''),
'request_data': request.data,
})
urlpatterns = [
url(r'^view/$', view),
]
@override_settings(ROOT_URLCONF='github.tests.test_payload_factories.test_roundtrip')
class TestRoundtrip(TestCase):
def test_round_trip(self):
"""
A DRF Request can be loaded via stub view
"""
request_factory = APIRequestFactory()
request = request_factory.post(
'/view/',
data={'hello': 'world'},
format='json',
)
result = view(request)
self.assertEqual(result.data['request_data'], {'hello': 'world'})
self.assertEqual(result.data['header_github_event'], '')
哪些通过:D