Querying the database in a Django unit test

Question:

I am creating a web application which has a POST endpoint, that does two things:

  1. Saves the POSTed data (a university review) in the database.
  2. Redirects the user to an overview page.

Here is the code for it:

if request.method == 'POST':
    review = Review(university=university,
                    user=User.objects.get(pk=1),
                    summary=request.POST['summary'])

    review.save()

    return HttpResponseRedirect(reverse('university_overview', args=(university_id,)))

I haven’t yet implemented passing the user data to the endpoint, and that’s why I’m saving everything under the user with pk=1.

My test is as follows:

class UniversityAddReviewTestCase(TestCase):
    def setUp(self):
        user = User.objects.create(username="username", password="password", email="email")
        university = University.objects.create(name="Oxford University", country="UK", info="Meh", rating="9")
        Review.objects.create(university=university, summary="Very nice", user_id=user.id)
        Review.objects.create(university=university, summary="Very bad", user_id=user.id)

        new_review = {
            'summary': 'It was okay.'
        }

        self.response = Client().post('/%s/reviews/add' % university.id, new_review)

    def test_database_updated(self):
        self.assertEqual(len(Review.objects.all()), 3)

The result is this:

  File ".../core/views.py", line 20, in detail
    user=User.objects.get(pk=1),
  File ".../ENV/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File ".../ENV/lib/python3.6/site-packages/django/db/models/query.py", line 403, in get
    self.model._meta.object_name
django.contrib.auth.models.DoesNotExist: User matching query does not exist.

Why is this happening? I know the user I’m creating has a pk=1, as when I actually print it during the test it’s 1.

Asked By: pavlos163

||

Answers:

pk is defined by the database. Something could make it not equal to 1 in your test.

Try this in your setUp method

user = User.objects.create_user(
    username="username",
    password="password",
    email="[email protected]",
    id=1
)
assert user.pk == 1
Answered By: Code Review Doctor

Take advantage of using self and then you can try this instead:

class UniversityAddReviewTestCase(TestCase):
    def setUp(self):
        self.user = User.objects.create(
            username="username", 
            password="password", 
            email="email")

        ....

and then

if request.method == 'POST':
    review = Review(
        university=university,
        user=self.user,
        summary=request.POST['summary'])

review.save()

I could make it work, with the following lines:

import unittest # instead of (from django.test import TestCase)

class NameTest(unittest.TestCase):
    #lines to test your code here...
Answered By: YAMPO
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.