Django unit test - How to assert that the custom dispatcher calls the UserManager.create_user method?

I am new to unit tests and mocking Python as well as Django.

Here is my model (simplified):

from django.db import models
from django.contrib.auth.models import User


class KangaUserManager(models.Manager):
    def create(self, username, email, password, last_name, first_name, request, registered=True, send_confirmation=True):
        kanga_user = KangaUser()
        kanga_user.user = User.objects.create_user(
            username=username,
            email=email,
            password=password,
            first_name=first_name,
            last_name=last_name
        )
        return kanga_user

class KangaUser(models.Model):
    objects = KangaUserManager()

    user = models.OneToOneField(User)

      

I would like to assert that User.objects.create_user is being called without naming it. I can see that the library layout is the one I need, but I don't understand anything.

I've tried things like this:

def test_create(self):
    with mock.patch('django.contrib.auth.models.UserManager') as usermanager_mock:
        kangauser_manager = KangaUserManager()
        kangauser_manager.create(self.username, self.email, self.password, self.last_name, self.first_name, self.request, self.registered, self.send_confirmation)

        self.assertTrue(usermanager_mock.create_user.called)

      

and that (and more I can't remember: D)

def test_create(self):
    with mock.patch('django.contrib.auth.models.User') as user_mock:
        user_mock.objects = mock.MagicMock()
        user_mock.objects.create_user = mock.MagicMock()

        kangauser_manager = KangaUserManager()
        kangauser_manager.create(self.username, self.email, self.password, self.last_name, self.first_name, self.request, self.registered, self.send_confirmation)

        self.assertTrue(user_mock.objects.create_user.called)

      

But I always see that the method is not called

What am I doing wrong?

(change 1: added import)

Edit 2:

While creating an adaptation suggested by Alex Martelli, I came across another error,

ValueError: Cannot assign "<MagicMock name='User.objects.create_user()' id='55229392'>": "KangaUser.user" must be a "User" instance.

      

Here's the adapted code:

from django.db import models
from django.contrib.auth import models as auth_model


class KangaUserManager(models.Manager):
    def create(self, username, email, password, last_name, first_name, request, registered=True, send_confirmation=True):
        kanga_user = KangaUser()
        kanga_user.user = auth_model.User.objects.create_user(
            username=username,
            email=email,
            password=password,
            first_name=first_name,
            last_name=last_name
        )
        return kanga_user

class KangaUser(models.Model):
    objects = KangaUserManager()

    user = models.OneToOneField(auth_model.User)

      

+3


source to share


2 answers


Okay thanks to Alex and Aaron, I got the advantage I need to make it work the way I wanted it, thanks!

So here is the code

from django.db import models
from django.contrib.auth import models as auth_model


class KangaUserManager(models.Manager):
    def create(self, username, email, password, last_name, first_name, request, registered=True, send_confirmation=True):
        kanga_user = KangaUser()
        kanga_user.user = auth_model.User.objects.create_user(
            username=username,
            email=email,
            password=password,
            first_name=first_name,
            last_name=last_name
        )
        return kanga_user

class KangaUser(models.Model):
    objects = KangaUserManager()

    user = models.OneToOneField(auth_model.User)

      



And a test that works:

def test_create(self):
    with mock.patch('django.contrib.auth.models.User') as user_mock:
        user_mock.objects = mock.MagicMock()
        user_mock.objects.create_user = mock.MagicMock()
        user_mock.objects.create_user.return_value = User()

        kangauser_manager = KangaUserManager()
        kangauser_manager.create(self.username, self.email, self.password, self.last_name, self.first_name, self.request, self.registered, self.send_confirmation)

        self.assertTrue(user_mock.objects.create_user.called)

      

-1


source


You need to return the value when using MagicMock.



from unittest.mock import MagicMock

thing = KangaUserManager()
thing.create_user = MagicMock(return_value=True)
self.assertTrue(thing.create_user(**user_kwargs))

      

+1


source







All Articles