python - django rest 框架错误单元测试 : TypeError: object of type 'type' has no len()

标签 python django unit-testing django-rest-framework

我目前正在使用 django-rest-framework 中的 jwt token 身份验证在 django 中编写自定义用户模型。在我的单元测试用例中,出现此错误:

Creating test database for alias 'default'...
Destroying test database for alias 'default'...
E
======================================================================
ERROR: test_token_sign_in (edea.authentication.tests.tests.AuthenticationTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\Home\midoriiro\Programming\workspace\edea\edea\authentication\tests\tests.py", line 17, in test_token_sign_in
    response = self.client.post(url, data, format='json')
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\rest_framework\test.py", line 170, in post
    path, data=data, format=format, content_type=content_type, **extra)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\rest_framework\test.py", line 92, in post
    return self.generic('POST', path, data, content_type, **extra)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\django\test\client.py", line 380, in generic
    return self.request(**r)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\rest_framework\test.py", line 159, in request
    return super(APIClient, self).request(**kwargs)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\rest_framework\test.py", line 111, in request
    request = super(APIRequestFactory, self).request(**kwargs)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\django\test\client.py", line 467, in request
    six.reraise(*exc_info)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\django\utils\six.py", line 686, in reraise
    raise value
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\django\views\generic\base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\rest_framework\views.py", line 451, in dispatch
    self.headers = self.default_response_headers  # deprecate?
  File "C:\Program Files (x86)\Python 3.5\lib\site-packages\rest_framework\views.py", line 150, in default_response_headers
    if len(self.renderer_classes) > 1:
TypeError: object of type 'type' has no len()

----------------------------------------------------------------------
Ran 1 test in 0.065s

FAILED (errors=1)

Process finished with exit code 1

还有我的测试代码:

from django.core.urlresolvers import reverse_lazy

from rest_framework import status
from rest_framework.test import APITestCase

from edea.authentication.models import User

class AuthenticationTestCase(APITestCase):
    @classmethod
    def setUpTestData(cls):
        cls.user = User.objects.create_user('lol@lol.com', '0123456789')

    def test_token_sign_in(self):
        url = reverse_lazy('authentication-sign-in')
        data = {'email': 'lol@lol.com', 'password': '0123456789'}

        response = self.client.post(url, data, format='json')

        token = response.json()['token']

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertEqual(token, self.user.token)

我的观点:

from datetime import timedelta

from rest_framework.response import Response
from rest_framework import status

from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.views import JSONWebTokenAPIView

from edea.authentication.serializers import GetJWTSerializer, VerifyJWTSerializer, RefreshJWTSerializer, DestroyJWTSerializer

class GetJWTView(JSONWebTokenAPIView):
    serializer_class = GetJWTSerializer

class VerifyJWTView(JSONWebTokenAPIView):
    serializer_class = VerifyJWTSerializer

class RefreshJWTView(JSONWebTokenAPIView):
    serializer_class = RefreshJWTSerializer

class DestroyJWTView(JSONWebTokenAPIView):
    serializer_class = DestroyJWTSerializer

    def post(self, request):
        response = super(DestroyJWTView, self).post(request)

        if response.status_code is not status.HTTP_200_OK:
            return response

        return Response(status=status.HTTP_200_OK)

class TimeJWTView(JSONWebTokenAPIView):
    serializer_class = VerifyJWTSerializer

    def post(self, request):
        response = super(TimeJWTView, self).post(request)

        if response.status_code is status.HTTP_200_OK:
            expiration_time = None
            refresh_time = None

            if api_settings.JWT_VERIFY_EXPIRATION:
                expiration_time = api_settings.JWT_EXPIRATION_DELTA

                if isinstance(expiration_time, timedelta):
                    expiration_time = expiration_time.total_seconds()
                else:
                    expiration_time = -1

            if api_settings.JWT_ALLOW_REFRESH:
                refresh_time = api_settings.JWT_REFRESH_EXPIRATION_DELTA

                if isinstance(refresh_time, timedelta):
                    refresh_time = refresh_time.total_seconds()
                else:
                    refresh_time = -1

            response.data['expiration_time'] = expiration_time
            response.data['refresh_time'] = refresh_time

            return response

我不明白这个错误,我没有在我的 View 中定义任何 renderer_classes,所以 renderer_classes 必须为 0?

感谢帮助!

最佳答案

问题是您在 REST_FRAMEWORK 中缺少尾随命令设置,特别是 DEFAULT_RENDERER_CLASSES 的键.

REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": (
        "rest_framework.renderers.JSONRenderer"
    )
}

只要在列表中的每个元素后添加一个逗号,就永远不会出现此问题。

REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": (
        "rest_framework.renderers.JSONRenderer",
    )
}

那是因为否则它会被解释为

REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": "rest_framework.renderers.JSONRenderer",
}

这绝对不是您要找的。

关于python - django rest 框架错误单元测试 : TypeError: object of type 'type' has no len(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35053308/

相关文章:

python - pybind11 与 numpy 的矩阵乘积

python - 根据从 python 中的其他两个字符串列应用的条件创建一个新列

python - grequests 与 requests 发生冲突

android - 为什么大型 Android Activity 单元测试会失败?

python - PyCharm:创建测试 --> 目标目录?

python - 根据 pandas 中的行值选择列,并使用列索引进行子集化

python - 为什么我无法在此嵌套字典中创建其他键?

python - 我如何安排在 django 中的某个时间发送电子邮件?

python - Django REST框架: Two models nested via a third one (with 2 FKs )

c# - 如何使用 NSubstitute 框架验证接收到具有特殊类型的 AddSingleton