Django测试RequestFactory无法获取路由参数的解决方法

4

我有一个问题,我不知道如何使它工作。

urls.py:

urlpatterns = [
    url(r'athletes/search$', SearchAthletes.as_view()),
    url(r'athletes/([0-9]+)$', ViewAthlete.as_view())
]

views.py:

class ViewAthlete(APIView):

    def get(self, request, id, format=None):
        athlete = Athlete.objects.get(id=id)
        serializer = AthleteSerializer(athlete)
        return Response(serializer.data)

test.py:

def test_view_athlete(self):
    tmp = Athlete.objects.order_by('?')[0]

    request = self.factory.get('/_api/v1/athletes/' + str(tmp.id))
    request.user = AnonymousUser()

    response = ViewAthlete.as_view()(request)
    self.assertEquals(response.data.id, tmp.id)

我一直在收到以下错误:
Traceback (most recent call last): File "/tests.py", line 44, in test_view_athlete response = ViewAthlete.as_view()(request) File "/venv/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view return view_func(*args, **kwargs) File "/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view return self.dispatch(request, *args, **kwargs) File "/venv/lib/python3.5/site-packages/rest_framework/views.py", line 474, in dispatch response = self.handle_exception(exc) File "/venv/lib/python3.5/site-packages/rest_framework/views.py", line 471, in dispatch response = handler(request, *args, **kwargs) TypeError: get() missing 1 required positional argument: 'id'
据我理解,问题是在于没有将id参数传递给ViewAthelete视图类的get函数。这是什么原因呢?在开发环境(非测试)下,它会显示数据,但测试环境不会识别路由中的参数。
2个回答

7
据我所知,urlpatterns 在通过完整的 Django 请求堆栈进行测试时被考虑在内,例如:通过 django.test.Client 并使用其 get/post 方法。
当直接测试您的视图 (MyView.as_view()(request)) 时,整个 URL 解析器逻辑被绕过,然后需要由调用者提供 args/kwargs(例如:MyView.as_view()(request, 'arg1', 'arg2', id='34'))。

6

正如zsepi所说,这里不使用您的URL。为了避免重复参数,而不是直接调用视图,您可以使用测试客户端来“调用”URL:这样做的另一个好处是中间件运行,因此您无需单独分配用户属性。

response = self.client.get('/_api/v1/athletes/' + str(tmp.id)) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接