使用API​​RequestFactory进行Django测试:如何将“ flat”参数传递给视图

时间:2019-06-12 10:56:08

标签: django url testing parameters request

Django 2.2

我正在使用API​​RequestFactory编写API测试。命中的代码 /some_endpoint/some_endpoint/<item_id>已经可以使用,测试/some_endpoint的测试也可以使用。但是,测试/some_endpoint/<item_id>的测试无法正常工作,因为我找不到将<item_id>值传递给视图代码的有效方法。请注意,它不是/some_endpoint/<some_keyword>=<item_id>,在我来说是“扁平”的,即没有关键字。问题是<item_id>不能进入视图代码(在None方法的类视图中,它始终是get_queryset

我尝试将其传递为**kwargs,但它也未到达(请参见here)。但是,如果没有关键字,那可能还是行不通的。

我试图切换为使用Client而不是APIRequestFactory,结果相同。但是我宁愿让它与APIRequestFactory一起使用,除非它通常不能以这种方式工作。下面是代码。

test.py

def test_getByLongId(self) :
    factory = APIRequestFactory()
    item = Item.active.get(id=1)
    print(item.longid)
    #it prints correct longid here

    request = factory.get("/item/%s" % item.longid)
    view = ItemList.as_view()
    force_authenticate(request, user=self.user)
    response = view(request)

urls.py

urlpatterns = [
    ...
    ...
    url(item/(?P<item_id>[a-zA-Z0-9-]+)/$', views.ItemList.as_view(), name='item-detail'),
    ...
    ...
]

views.py

class ItemList(generics.ListAPIView):
    permission_classes = (IsBotOrReadOnly,)

    """
    API endpoint that allows users to be viewed or edited.
    """
    serializer_class = ItemSerializer

    schema = AutoSchema(
        manual_fields=[
            coreapi.Field("longid"),
        ]
    )

    def get_queryset(self):
        """
        Optionally restricts the returned SampleSequencing to a given barcode.
        """
        longid = self.kwargs.get('item_id', None)

        print(longid)
        #prints correct longid when executed by the webserver code and prints None when executed by the test

        queryset = Item.active.filter(longid=longid)
        return queryset

1 个答案:

答案 0 :(得分:1)

您必须将item_id传递到view()

def test_by_long_id(self) :
    factory = APIRequestFactory()
    item = Item.active.get(id=1)
    print(item.longid)
    #it prints correct longid here

    request = factory.get("/item/%s" % item.longid)
    view = ItemList.as_view()
    force_authenticate(request, user=self.user)
    response = view(request, item_id=item.longid)

或使用API​​Client:

from rest_framework.test import APIClient

# ...
#
    def test_item_client(self):
        item = Item.active.get(id=1)
        client = APIClient()
        url = '/item/%s/' % item.id
        response = client.get(url)