Answer the question
In order to leave comments, you need to log in
How to fix a failing test (Django Rest Framework)?
Beaver everyone. Explain where I'm wrong? Last test fails
AssertionError: Expected view AuthorViewSet to be called with a URL keyword argument named "id".
Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
from rest_framework.reverse import reverse_lazy
from rest_framework.test import APIRequestFactory
from src.apps.book.factories import AuthorFactory, BookFactory
from src.apps.book.views import AuthorViewSet, BookViewSet
class BookViewSetTestCase(TestCase):
def setUp(self):
super(BookSerializerTestCase, self).setUp()
self.authors = AuthorFactory.create_batch(size=2)
self.books = BookFactory.create_batch(size=2, author=self.authors[0])
self.factory = APIRequestFactory()
def tearDown(self):
super(BookSerializerTestCase, self).tearDown()
AuthorFactory.reset_sequence()
BookFactory.reset_sequence()
def test_author_list_view_set(self):
view = AuthorViewSet.as_view({'get': 'list'})
request = self.factory.get(reverse_lazy('author-list'))
response = view(request)
response.render()
self.assertEqual(response.status_code, 200)
def test_author_retrieve_view_set(self):
view = AuthorViewSet.as_view({'get': 'retrieve'})
request = self.factory.get(reverse_lazy('author-detail', args=(self.authors[0].pk,)))
response = view(request)
response.render()
self.assertEqual(response.status_code, 200)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from rest_framework import viewsets
from rest_framework_extensions.mixins import DetailSerializerMixin
from src.apps.book.models import AuthorModel, BookModel
from src.apps.book.permissions import IsAccountAdminOrReadOnly
from src.apps.book.serializers import AuthorListSerializer, AuthorRetrieveSerializer, BookSerializer
class AuthorViewSet(DetailSerializerMixin, viewsets.ModelViewSet):
model = AuthorModel
queryset = AuthorModel.objects.prefetch_related('books').all()
serializer_class = AuthorListSerializer
serializer_detail_class = AuthorRetrieveSerializer
permission_classes = [
IsAccountAdminOrReadOnly
]
lookup_field = 'id'
class BookViewSet(viewsets.ModelViewSet):
model = BookModel
queryset = BookModel.objects.select_related('author').all()
serializer_class = BookSerializer
permission_classes = [
IsAccountAdminOrReadOnly
]
lookup_field = 'isbn'
Answer the question
In order to leave comments, you need to log in
It was necessary to transfer the value of the id field for the author and isbn for the book in the view call. Like this:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from rest_framework.reverse import reverse_lazy
from rest_framework.test import APIRequestFactory, APITestCase
from src.apps.book.factories import AuthorFactory, BookFactory
from src.apps.book.views import AuthorViewSet, BookViewSet
class BookSerializerTestCase(APITestCase):
def setUp(self):
super(BookSerializerTestCase, self).setUp()
self.authors = AuthorFactory.create_batch(size=2)
self.books = BookFactory.create_batch(size=2, author=self.authors[0])
self.factory = APIRequestFactory()
def tearDown(self):
super(BookSerializerTestCase, self).tearDown()
AuthorFactory.reset_sequence()
BookFactory.reset_sequence()
def test_author_list_view_set(self):
view = AuthorViewSet.as_view({'get': 'list'})
request = self.factory.get(reverse_lazy('author-list'))
response = view(request)
self.assertEqual(response.status_code, 200)
def test_author_retrieve_view_set(self):
view = AuthorViewSet.as_view({'get': 'retrieve'})
request = self.factory.get(reverse_lazy('author-detail', args=(self.authors[0].pk,)))
response = view(request, id=self.authors[0].pk)
self.assertEqual(response.status_code, 200)
def test_book_list_view_set(self):
view = BookViewSet.as_view({'get': 'list'})
request = self.factory.get(reverse_lazy('book-list'))
response = view(request)
self.assertEqual(response.status_code, 200)
def test_book_retrieve_view_set(self):
view = BookViewSet.as_view({'get': 'retrieve'})
request = self.factory.get(reverse_lazy('book-detail', args=(self.books[0].isbn,)))
response = view(request, isbn=self.books[0].isbn)
self.assertEqual(response.status_code, 200)
from rest_framework.test import APITestCase
class AccountTests(APITestCase):
def test_endpoint(self):
url = reverse('some_url')
response
= self.client.get(url)
As far as I understand, the code I provided will crash with a no reverse match error if you do not pass id. And, as I understand it, in your example, it is the id that is missing for the view. However, I have not seen that the view was simply pulled by as_view like that. This function returns, as far as I remember, another function (dispatch?), to which request and a pack of quargs (if declared) are passed. So it's correct to either reverse here, or do MyView.as_view()(request, *args, **kwargs).
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question