Search code examples
djangodjango-rest-frameworkdjango-testing

Django Restapi - How to test if POST saves data in database?


So I found this question: Django Rest Framework testing save POST request data

And I understood that the data created with POST request should be accessible as long as the function is running. So I made the whole test in one function:

class PostMovieAPITest(APITestCase):
    def test_correct_request(self):
        title = 'Snatch'
        response = self.client.post('/movies/', data={'title': title}, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        movies = Movie.objects.all()
        self.assertTrue(Movie.objects.get(title=title))

The problem is, Movie.objects.all() is empty, even though I send a CREATE/POST request in the same function. The API works fine when I do `manage.py runserver' and test it in browser. But how can write a proper test to check if data is actually saved in database?

urls.py:

from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from api import views


router = routers.DefaultRouter()
router.register(r'movies', views.MovieViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('admin/', admin.site.urls),
]

views.py:

class MovieViewSet(viewsets.ModelViewSet):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

    def create(self, request, *args, **kwargs):
        title = request.data.get('title')
        if not title:
            return Response({'Error': "Body should be {'title':'The title of the Movie'}"}, status=status.HTTP_400_BAD_REQUEST)

        data = get_data_from_omdb(title)

        if len(data) == 0:
            return Response({"Error": "Title does not exist in OMDB database"}, status=status.HTTP_400_BAD_REQUEST)

        serializer = MovieSerializer(data=data, context={'request': request})

        if serializer.is_valid(raise_exception=False):
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Solution

  • Found the problem thanks to Ozgur Akcali's comment. I couldn't get the movie because Movie object was created based on data from external API, including the title.

    "Hire me!" -> "Hire Me!"

    Sometimes scripting makes me want to kill. Thanks a lot and sorry for wasting your time.

    def test_correct_request(self):
        title = 'Hire Me!' # was: 'Hire me!'
        response = self.client.post('/movies/', data={'title': title}, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertTrue(Movie.objects.get(title=title))