Подтвердить что ты не робот

Django Rest Framework - Как проверить ViewSet?

У меня возникли проблемы с тестированием ViewSet:

class ViewSetTest(TestCase):
    def test_view_set(self):
        factory = APIRequestFactory()
        view = CatViewSet.as_view()
        cat = Cat(name="bob")
        cat.save()

        request = factory.get(reverse('cat-detail', args=(cat.pk,)))
        response = view(request)

Я пытаюсь реплицировать синтаксис здесь:

http://www.django-rest-framework.org/api-guide/testing#forcing-authentication

Но я думаю, что их вид AccountDetail отличается от моего ViewSet, поэтому я получаю эту ошибку из последней строки:

AttributeError: 'NoneType' object has no attributes 'items'

Есть ли здесь правильный синтаксис или я смешиваю понятия? Мои тесты APIClient работают, но я использую factory здесь, потому что в конце концов мне захочется добавить "request.user = some_user". Спасибо заранее!

О, и клиентский тест работает нормально:

def test_client_view(self):
    response = APIClient().get(reverse('cat-detail', args=(cat.pk,)))
    self.assertEqual(response.status_code, 200)
4b9b3361

Ответ 1

Я думаю, что нашел правильный синтаксис, но не уверен, что он обычный (новичок в Django):

def test_view_set(self):
    request = APIRequestFactory().get("")
    cat_detail = CatViewSet.as_view({'get': 'retrieve'})
    cat = Cat.objects.create(name="bob")
    response = cat_detail(request, pk=cat.pk)
    self.assertEqual(response.status_code, 200)

Итак, теперь это проходит, и я могу назначить request.user, который позволяет мне настроить метод извлечения в CatViewSet, чтобы рассмотреть пользователя.

Ответ 2

У меня была такая же проблема, и я смог найти решение.

Взглянув на исходный код, похоже, что в представлении предполагается, что существует аргумент "действия", в котором есть элементы метода (так, dict).

https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/viewsets.py#L69

Вот откуда исходит ошибка. Вам нужно будет указать действия аргумента с помощью dict, содержащего разрешенные действия для этого вида, а затем вы сможете проверить правильность представления.

Общее отображение:

{
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
}

http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers

В вашем случае вам нужно {'get': 'retrieve'} Например:

class ViewSetTest(TestCase):
    def test_view_set(self):
        factory = APIRequestFactory()
        view = CatViewSet.as_view(actions={'get': 'retrieve'}) # <-- Changed line
        cat = Cat(name="bob")
        cat.save()

        request = factory.get(reverse('cat-detail', args=(cat.pk,)))
        response = view(request)

EDIT: вам действительно нужно указать необходимые действия. Измененный код и комментарии, чтобы отразить это.

Ответ 3

Я думаю, это твоя последняя строка. Вы должны вызвать CatViewSet as_view(). Я бы пошел с:

response = view(request)

учитывая, что вы уже определили view = CatViewSet.as_view()

EDIT:

Можете ли вы показать свой views.py? В частности, какой тип ViewSet вы использовали? Я копаю код DRF, и похоже, что у вас могут не быть какие-либо действия, сопоставленные с вашим представлением ViewSet, который вызывает ошибку.

Ответ 4

Я нашел способ сделать это без необходимости вручную создавать правильный viewet и давать ему сопоставление действий:

from django.core.urlresolvers import reverse, resolve
...
url = reverse('cat-list')
req = factory.get(url)
view = resolve(url).func
response = view(req)
response.render()