Search code examples
djangopython-3.xunit-testingdjango-rest-frameworktestcase

Django model unit test


I started learning Django, and I'm having problems with the unit test, and I was trying to look for the problem, but I can not identify what the problem is in my code. If someone can identify what the problem is in my code or if you can give me some advice?

Error:

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: test_create_user (user_api.tests.ModelUseProfileTest)
Users can register
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/vagrant/src/api/user_api/tests.py", line 26, in test_create_user
    user = UserProfile.objects.get(id=1)
  File "/home/ubuntu/.virtualenvs/venv/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/ubuntu/.virtualenvs/venv/lib/python3.5/site-packages/django/db/models/query.py", line 379, in get
    self.model._meta.object_name
user_api.models.DoesNotExist: UserProfile matching query does not exist.
----------------------------------------------------------------------
Ran 1 test in 0.040s
FAILED (errors=1)
Destroying test database for alias 'default'...

My test:

from django.test import TestCase
from rest_framework import status
from django.core.urlresolvers import reverse
from .models import UserProfile

# Create your tests here.
class ModelUseProfileTest(TestCase):
 """ Test class define the test suite for the UserProfile model."""

    def test_create_user(self):
    """Users can register"""

    # Create an instance of a GET request.
    response = self.client.post("/api/v1/register/", {
      "name": "Walter",
      "lasT_name": "White",
      "email": "[email protected]", 
      "password": "secret", })

    user = UserProfile.objects.get(id=1)

    self.assertEqual(user.name, "Walter")
    self.assertEqual(user.last_name, "White")
    self.assertEqual(user.email, "[email protected]")
    self.assertEqual(response.status_code, 201)

My model:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.models import BaseUserManager

class UserProfileManager(BaseUserManager):
      """Helps Django work with our custom user model"""
      def create_user(self, name, last_name, email, password=None):
            """Create a new user profile object."""
            if not email:
                  raise ValueError('Users must have an email address.')

            if not name:
                  raise ValueError('Users must have an name.')

            if not last_name:
                  raise ValueError('Users must have an last name.')

            email = normalize_email(email)
            user = self.model(name=name, last_name=last_name, email=email)
            user.set_password(password)
            user.save(using=self._db)

            return user

      def create_superuser(self, name, last_name, email, password=None):
            """Create and saves a new superuser with given details."""

            user = self.create_user(name, last_name, email, password)
            user.is_superuser = True
            user.is_staff = True
            user.save(using=self._db)

            return user

class UserProfile(AbstractBaseUser, PermissionsMixin):
      """Represents a "user profile" inside our system."""

      name = models.CharField(max_length=500)
      last_name = models.CharField(max_length=500)
      email = models.EmailField(max_length=255, unique=True)
      is_active = models.BooleanField(default=True)
      is_staff = models.BooleanField(default=False)
      objects = UserProfileManager()
      USERNAME_FIELD = 'email'
      REQUIRED_FIELDS = ['name', 'last_name']

      def get_full_name(self):
        """Used to get a users full name."""

          return self.name

      def get_short_name(self):
        """Used to get a users short name."""

          return self.name

      def __str__(self):
        """Django uses this when it needs to convert the object to a string"""

          return self.email

Solution

  • Although the test client starts from a blank database each time, that's no reason to assume that the primary key is 1; sequences are not reset when the tables are emptied after each run. Instead of explicitly getting pk=1, you should just query for the first item:

     user = UserProfile.objects.first()