2

I have problem with testing API built in DRF tutorial: https://www.django-rest-framework.org/tutorial/1-serialization/

I have view:

class SnippetList(generics.ListCreateAPIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

And test class for testing that view:

class SnippetsList(APITestCase):
    def setUp(self):
        self.user = User.objects.create_superuser(username='testowy', password='test')
        self.client = APIClient()
        Snippet.objects.create(code="print('hello')", owner=self.user)
        Snippet.objects.create(code="print('world')", owner=self.user)
        self.payload = {
            "code": "print(edit)"
        }

    def test_get_snippets_list(self):
        response = self.client.get(reverse('snippet_list'))
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        self.assertEqual(response.data, serializer.data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_post_snippets_list(self):
        self.client.force_authenticate(self.user)
        response = self.client.post(reverse('snippet_list'), json.dumps(self.payload), format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

When I run my tests with python manage.py test first test (for get method) is passing but for the second I get this output:

    self.assertEqual(response.status_code, status.HTTP_201_CREATED) AssertionError: 400 != 201

In manual tests after login in everything works perfectly, does anyone knows what am I missing here?

Fifekk
  • 21
  • 1
  • 4
  • This post here has a good jumping off point for your issue. https://stackoverflow.com/questions/2619102/djangos-self-client-login-does-not-work-in-unit-tests – SZuber Apr 07 '21 at 20:40

1 Answers1

2

force_authenticate is called inside of the setUp method.

a better practice might be to create a class for PublicTests, which would have a regular user.

and then make a new class called PrivateTests in which you would force_authenticate inside of the setUp()

def setUp(self):
    self.user = User.objects.create_superuser(username='testowy', password='test')
    self.client = APIClient()
    self.client.force_authenticate(user=self.user)

def test_get_snippets_list(self):
    """Test creating and listing snippet objects."""

    snippet1 = Snippet.objects.create(code="print('hello')", owner=self.user)
    snippet2 = Snippet.objects.create(code="print('world')", owner=self.user)

    user = self.user
    res = self.client.get(reverse("snippet_list"))

    self.assertEqual(res.status_code, status.HTTP_200_OK)
    self.assertEqual(user.snippets.count(), 2)
    self.assertIn(snippet1, user.snippets.all())
    self.assertIn(snippet2, user.snippets.all())
matpvl
  • 63
  • 6