让我说我有这个APIView
class Dummy(APIView):
def get(self, request):
return Response(data=request.query_params.get('uuid'))
要测试它,我需要创建一个请求对象以传递到get
函数
def test_dummy(self):
from rest_framework.test import APIRequestFactory
factory = APIRequestFactory()
request = factory.get('/?uuid=abcd')
DummyView().get(request)
抱怨AttributeError: 'WSGIRequest' object has no attribute 'query_params'
仔细观察,工厂会创建WSGIRequest
个实例,而不是DRF版本<class 'rest_framework.request.Request'>
。
>>> from rest_framework.test import APIRequestFactory
>>> factory = APIRequestFactory()
>>> request = factory.get('/')
>>> request.__class__
<class 'django.core.handlers.wsgi.WSGIRequest'>
答案 0 :(得分:14)
请参阅Tom的解决方案,DummyView()(request)
会引发错误:
TypeError: 'DummyView' object is not callable
相反,应该像使用as_view
中的urls.py
一样使用DummyView.as_view()(request)
:
as_view
DRF from rest_framework.views import APIView
APIView().initialize_request(request)
>>> <rest_framework.request.Request object at 0xad9850c>
使用method initialize_request
将Django Request对象转换为DRF版本。您可以尝试:
from rest_framework.test import APIClient
client = APIClient()
client.post('/notes/', {'title': 'new idea'}, format='json')
您也可以使用APIClient来运行测试。它还测试URL调度。
{{1}}
答案 1 :(得分:11)
那是对的。目前APIRequestFactory
返回一个HttpRequest
对象,只有在到达视图层后才会升级到REST框架Request
对象。
这反映了您在实际请求中看到的行为,以及做所做的事情是如何处理的。呈现JSON,XML或您为测试请求配置的任何其他内容类型。
但是我同意它的令人惊讶的行为,并且在某些时候它可能会返回一个Request
对象,而REST框架视图将确保它只对请求执行Request
升级那个HttpRequest
的实例。
您需要做的是实际上调用视图,而不是调用.get()
方法......
factory = APIRequestFactory()
request = factory.get('/?uuid=abcd')
view = DummyView.as_view()
response = view(request) # Calling the view, not calling `.get()`
答案 2 :(得分:0)
我知道这个问题是在提出问题后的一段时间,但是它为我解决了这个问题。只需重写APIRequestFactory
类,如下所示。
# Override APIRequestFactory to add the query_params attribute.
class MyAPIRequestFactory(APIRequestFactory):
def generic(self, method, path, data='',
content_type='application/octet-stream', secure=False,
**extra):
# Include the CONTENT_TYPE, regardless of whether or not data is empty.
if content_type is not None:
extra['CONTENT_TYPE'] = str(content_type)
request = super(MyAPIRequestFactory, self).generic(
method, path, data, content_type, secure, **extra)
request.query_params = request.GET
return request