How to fix "TypeError: argument of type 'ConnectionHandler' is not iterable" when running a django test?
Asked Answered
V

1

5

When I do ```python -m unittest`` inside of my users app, I get this error:

TypeError: argument of type 'ConnectionHandler' is not iterable

I was customizing my User model in django and I wanted to make a test for it. I already did the migrations and the custom User model works good (I did with a new database), so I expected to run the test successfully. Here is my test code:

from django.test import TestCase
from django.contrib.auth import get_user_model

# Create your tests here.
class UsersManagersTests(TestCase):

    def test_create_user(self):
        User = get_user_model()
        user = User.objects.create_user(email='[email protected]', password='foo')
        self.assertEqual(user.email, '[email protected]')
        self.assertTrue(user.is_active)
        self.assertFalse(user.is_staff)
        self.assertFalse(user.is_superuser)
        try:
            # username is None for the AbstractUser option
            # username does not exist for the AbstractBaseUser option
            self.assertIsNone(user.username)
        except AttributeError:
            pass
        with self.assertRaises(TypeError):
            User.objects.create_user()
        with self.assertRaises(TypeError):
            User.objects.create_user(email='')
        with self.assertRaises(ValueError):
            User.objects.create_user(email='', password="foo")

    def test_create_superuser(self):
        User = get_user_model()
        admin_user = User.objects.create_superuser('[email protected]', 'foo')
        self.assertEqual(admin_user.email, '[email protected]')
        self.assertTrue(admin_user.is_active)
        self.assertTrue(admin_user.is_staff)
        self.assertTrue(admin_user.is_superuser)
        try:
            # username is None for the AbstractUser option
            # username does not exist for the AbstractBaseUser option
            self.assertIsNone(admin_user.username)
        except AttributeError:
            pass
        with self.assertRaises(ValueError):
            User.objects.create_superuser(
                email='[email protected]', password='foo', is_superuser=False)

settings.py

AUTH_USER_MODEL = 'users.CustomUser'

models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import gettext_lazy as _
from django.utils import timezone

from .managers import CustomUserManager

# Create your models here.
class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email address'), unique=True)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_deleted = models.BooleanField(default=False)
    date_joined = models.DateTimeField(default=timezone.now)
    updated_date=models.DateTimeField(auto_now=True)
    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
        ('O', 'Others'),
    )
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    def __str__(self):
        return self.email

managers.py

from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _


class CustomUserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifiers
    for authentication instead of usernames.
    """
    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 Email must be set'))
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    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)
        extra_fields.setdefault('is_active', 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)

Why does the test fail?

Velarium answered 6/6, 2019 at 20:28 Comment(0)
F
4

The error is probably due to the configuration of your IDE. What happens when you run "python manage.py test" ?

Fattal answered 6/6, 2019 at 23:11 Comment(4)
In manage.py path, I ran that command and I get: Creating test database for alias 'default'... System check identified no issues (0 silenced). .. ---------------------------------------------------------------------- Ran 2 tests in 0.575s OK Destroying test database for alias 'default'... So I'm not sure if the test is running correctly or notVelarium
It is actually running, if you do "python manage.py test -v 2 " you will have more precision !Fattal
Thanks!, so by last, what is the difference between these two commands? "python -m unittest" and "python manage.py test"?Velarium
"python -m unittest" invokes the automatic test discovery from the unittest module (Python standard library) while "python manage.py test" runs the manage script provided by Django which then runs your unit tests. I do not know how exactly these two methods differ, but I guess with Django you would want to use the manage script.Decastyle

© 2022 - 2024 — McMap. All rights reserved.