Тест Django с APIRequestFactory: как передать «плоский» параметр в представление - PullRequest
0 голосов
/ 12 июня 2019

Django 2.2

Я пишу тесты для API с использованием APIRequestFactory.Код, который работает с /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, он также не приходит(см. здесь ).Но это, вероятно, не будет работать в любом случае без ключевого слова.

Я попытался перейти на использование 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 Ответ

1 голос
/ 12 июня 2019

Вы должны передать 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)

или использовать APIClient:

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