使用 APIRequestFactory 对 Django 的 rest api 进行单元测试时无法获取 url 参数

Hus*_*ain 7 python django rest

我使用 Django 的rest_framework. 它是使用基于类的视图创建的。

视图.py

import logging
from rest_framework.views import APIView
from rest_framework.authentication import BasicAuthentication, SessionAuthentication, TokenAuthentication
from rest_framework.response import Response

from handlers.product import get_data

log = logging.getLogger(__name__)

class ProductView(APIView):
    authentication_classes = (TokenAuthentication, BasicAuthentication, SessionAuthentication)

    def get(self, request, **kwargs):
        try:
            product_id = kwargs['product_id']
            response = get_data(product_id)
            return Response(response)
        except KeyError as key:
            log.exception(key)
            return Response({'error_msg': '{} is required'.format(key)}, status=400)
Run Code Online (Sandbox Code Playgroud)

网址.py

url(r'^product/(?P<product_id>[0-9]+)/data/$', ProductView.as_view(), name='product'),
Run Code Online (Sandbox Code Playgroud)

这就是我尝试过的,

import pytest
from django.contrib.auth.models import User
from mixer.backend.django import mixer
from rest_framework.authtoken.models import Token
from rest_framework.test import APIRequestFactory

from views import *

pytestmark = pytest.mark.django_db


@pytest.fixture()
def token():
    user = mixer.blend(User)
    return Token.objects.create(user=user)


class TestProductView:

    def test_get_data(self, token):
        factory = APIRequestFactory()
        request = factory.get('/product/100230/data/', HTTP_AUTHORIZATION='Token {}'.format(token))
        response = ProductView.as_view()(request)
        assert response.status_code == 200
Run Code Online (Sandbox Code Playgroud)

我的测试失败,因为我得到了一个例外,

KeyError: 'product_id'
Run Code Online (Sandbox Code Playgroud)

但是当我运行我的应用程序并从浏览器请求 api 时,它从 url 中获取 product_id。

请注意,我真的必须kwargsgetapi 方法中使用,因为稍后我想让 get_data 通用并将所有 url 参数和查询参数传递给它。


更新 (29/01/2018)

Django 测试客户端 ( django.test.Client) 来救援了!

我已经开始使用它,而不是RequestFactory每当我有 url 参数时。我不确定我是否应该把它作为这篇文章的答案。

Art*_*ate 0

RequestFactory 提供了一种生成请求实例的方法,该实例可以用作任何视图的第一个参数。下面视图中的“请求”:

\n
def view(request, url_parameter):\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n

django.test.Client 将模拟 URL 上的 GET 和 POST 请求,并观察响应 \xe2\x80\x93 从低级 HTTP(结果标头和状态代码)到页面内容的所有内容。

\n

这是直接来自文档的。但我将为任何展望未来的人提供答案。

\n
django.test.Client #Simulate 'GET' and 'POST' sides.\n
Run Code Online (Sandbox Code Playgroud)\n