Django Rest框架的测试请求不能由它自己的请求类来解析

2024-05-16 03:43:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个端点来使用Django Rest framework3接收和解析GitHub Webhook payloads。为了匹配有效负载规范,我正在编写一个有效负载请求工厂,并测试它是否正在生成有效的请求。在

但是,当尝试测试用DRF的Request类生成的请求时,问题就来了。这是我能想到的最小的失败测试-问题是用DRF的APIRequestFactory生成的请求似乎不能被DRF的Request类解析。这是预期的行为吗?在

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')

堆栈跟踪是:

^{pr2}$

我显然在做一些愚蠢的事情-我把编码搞得一团糟。。。意识到我需要将解析器列表传递给Request以避免UnsupportedMediaType错误,现在我被困在这里了。在

我应该做些不同的事吗?也许应该避免使用APIRequestFactory?或者用不同的方法测试我构建的GitHub请求?在


更多信息

GitHub向注册的webhook发送一个请求,该webhook有一个X-GitHub-Event头,因此为了测试我的webhook DRF代码,我需要能够在测试时模拟这个头。在

我成功实现这一点的途径是构建一个自定义请求,并使用工厂将有效负载加载到其中。这是我的工厂代码:

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

这个问题的出现是因为我想断言PayloadRequestFactory正在为各种传递的参数生成有效的请求,所以我试图解析它们并断言它们的有效性,但是DRF的Request类似乎无法实现这一点,因此我的问题是测试失败。在

所以,我的问题是-我应该如何测试PayloadRequestFactory正在生成我需要的请求?在


Tags: fromimportgithubrestdatarequestfactory工厂
2条回答

“老兄,我听说你喜欢请求,因为你把一个请求放在一个请求里”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.

希望这有帮助

看看tests for ^{} in DRFstub 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

相关问题 更多 >