简体   繁体   中英

Django Cusom User Manager Unit Test - NoneType object is not callable

This all started when I downloaded coverage.py and started testing my django project. Everything is fine, however I'm lacking coverage on a custom user manager I set up in Models.py

Here's the full code.

models.py

from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _

class UserManager(BaseUserManager):
    """Define a model manager for User model with no username field."""

    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        """Create and save a User with the given email and password."""
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)

        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        """Create and save a regular User with the given email and password."""
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        """Create and save a SuperUser with the given email and password."""
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields)


class CustomUser(AbstractUser):
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    # profile_image = models.ImageField(upload_to="users/profile_pic", blank=True)
    is_pastor = models.BooleanField(default=True)
    home_church = models.ForeignKey(
        'church.Church',
        on_delete="CASCADE",
        blank=True,
        null=True)

    username = None
    email = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager() ## This is the new line in the User model. ##

I'm attempting to test the "_create_user" function in the UserManager. Here is my code

test.py

class UserManagerTestCase(TestCase):

def test_main_create_user(self):
    manager = UserManager()
    user = manager._create_user('jdoe@gmail.com', 'password123')
    self.assertTrue(isinstance(user, User))

Unfortunately, when I call the '_create_user' function I get a Type Error: 'NoneType' object is not callable.

This is strange, because the model manager works as expected when creating users and I confirmed with print statements that both the email and **extra_fields arguments are not None.

Some research online said this might because the Manager is not designed to be called directly. Is that the case? If so, how should you handle unit testing?

Instantiate CustomUser() with values so it can be used to access the methods to be tested. UserManager CANNOT be used directly, it is only accessible through the Model it was created for: CustomUser.

#tests.py
class UserManagerTestCase(TestCase):
    def test_main_create_user(self):
        user = CustomUser.objects.create_user('jdoe@gmail.com', 'password123')
        self.assertTrue(isinstance(user, User))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM