Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test not passing in Django when it should

I just started with Django and thought maybe someone could enlighten me about a simple test I wrote that should pass but obviously doesn't. Well, I say it should but being pretty new to Django I guess my lack of knowledge is the reason it fails.

I extended the django User model with another model and a one to one relationship, as suggested in the docs, to add a field to the model. That model, namely UserStep, simply contains an Integer that starts at zero. I decided to extend the manager too to implement a method named setUserStep that set the step to a new value if the condition is met.

models.py

class UserStepManager(models.Manager):
    def setUserStep(self, user, conditional_step, step):
        if user.userstep.step == conditional_step:
            user.userstep.step = step
            user.userstep.save()


class UserStep(models.Model):
    """This model holds the user step count"""
    user = models.OneToOneField(User)
    step = models.IntegerField(default=0)
    # we set the custom manager
    objects = UserStepManager()

Then when the User signs up, a new UserStep object gets created.

models.py

@receiver(user_signed_up)
def complete_social_signup(sender, **kwargs):
    """We start step to 0"""
    user = kwargs.pop('user')
    us = UserStep(user=user)
    us.save()

I use the method setUserStep defined in the manager in one of my views that gets called when a user requests /phase1/step1/ URL. So, if the current step is zero, set it to 1. As simple as that.

views.py

@login_required
def step1(request):
    context_dict = {}
    UserStep.objects.setUserStep(request.user, 0, 1)
    return render(request, 'phase1/step1.html', context_dict)

I tested that behavior by hand by signing up and calling that view, and everything worked as expected. When I check the database, user.userstep.step is set to 1.

Then, being a good boy, I decided I would start writing some tests (I'm not at the point where I write the tests first yet, I should write tests to test my tests before that :P).

tests.py

class MyTests(TestCase):

    def setUp(self):
        self.test_user = User.objects.create_user(username="test",
                                                  email="[email protected]",
                                                  password="test")
        # Mock user_signed_up signal.
        us = UserStep(user=self.test_user)
        us.save()
        self.c = Client()

    def test_step_gets_incremented(self):
        self.c.login(username="test", password="test")
        response = self.c.get('/phase1/step1/')
        # user is logged in, the test should pass
        self.assertEqual(response.status_code, 200)
        current_user_step = self.test_user.userstep.step
        # Test doesn't pass. WHY ME
        self.assertEqual(current_user_step, 1)

AND BOOM AssertionError: 0 != 1

I'm even doing a simple print in my view method and it gets called as it should.

Thanks!

like image 966
Felix D. Avatar asked Dec 02 '25 15:12

Felix D.


1 Answers

You have to reload test_user from the database since changing of the user is performed to another user instance. That means if:

u1 = User.objects.get(id = 1)
u2 = User.objects.get(id = 1)

changes to u1 (even if saved) are not mirrored to u2. So you have to get again the user from the db after the request.

like image 70
JuniorCompressor Avatar answered Dec 05 '25 05:12

JuniorCompressor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!