How to test django session in django unittest?
Asked Answered
A

1

5

I have created view:

def forgot_password(request):
"""
Actions when user forgot password.
:param request: object
:return: redirect to views.home() or 'loginsys/forgot.html' with form, message
"""
message = None
if request.method == 'POST':
    form = ForgotPasswordForm(request.POST)
    if form.is_valid():
        email = form.cleaned_data['email']
        user = User.objects.filter(email=email)
        salt = random_salt(len(user[0].username))
        code = signing.dumps([user[0].id, user[0].email, user[0].username],
                             key=settings.SECRET_KEY, salt=salt)
        url = settings.SITE_URL + reverse('loginsys:reset', args=[code])
        send_email.apply_async(('Welcome', '<p>Hello</p><p><a href="{0}">Go to this link</a></p>'.
                                format(url), [email]))
        store = ForgotPasswordLink()
        store.random_salt = salt
        store.user_link_id = user[0].id
        store.code_value = code
        store.save()
        forgot_password_salt_life.apply_async((user[0].id, salt), countdown=180)
        request.session["message"] = 'Instruction have sent on your mail - {0}'.format(email)
        return redirect(reverse('home'))
else:
    form = ForgotPasswordForm()
return render(request, 'loginsys/forgot.html', {'form': form, 'message': message})

I have write message in session:

request.session["message"] = 'Instruction have sent on your mail - {0}'.format(email)

Then I have tested view:

def test_forgot_password(self):
    response = self.client.post(reverse('loginsys:forgot'), {'email': '[email protected]'})
    self.assertRedirects(response, reverse('home'), 302, 200)
    session = self.client.session
    self.assertEqual(session['message'], 'Instruction have sent on your mail - [email protected]')

And I have got error:

Error
Traceback (most recent call last):
  File "/home/maxim/PycharmProjects/SSHKeyStore/loginsys/tests.py", line 105, in test_forgot_password
    self.assertEqual(session['message'], 'Instruction have sent on your mail - [email protected]')
  File "/home/maxim/SSHKeyStoreVE/lib/python3.4/site-packages/django/contrib/sessions/backends/base.py", line 48, in __getitem__
    return self._session[key]
KeyError: 'message'

So I don't know what is the problem. I find some examples and make like there, but it doesn't help: Django testing stored session data in tests, How do I modify the session in the Django test framework, https://mcmap.net/q/804434/-setting-a-session-variable-in-django-tests error:

Error
Traceback (most recent call last):
  File "/home/maxim/PycharmProjects/SSHKeyStore/loginsys/tests.py", line 22, in setUp
    self.client.session = self.session
AttributeError: can't set attribute

I have got message:

RemovedInDjango19Warning: django.utils.importlib will be removed in Django 1.9.
  return f(*args, **kwds)

This is bad.

Please help me to fined solution and understand the problem ( may be solution is here Using session object in Django unit test but I didn't understand).

Thanks.

Absalom answered 1/8, 2015 at 18:41 Comment(0)
A
9

Define a mixin for this purpose like this

from django.test import Client
from importlib import import_module

class ModifySessionMixin(object):
    client = Client()

    def create_session(self):   
        session_engine = import_module(settings.SESSION_ENGINE)        
        store = session_engine.SessionStore()                          
        store.save()
        self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key

Now extend your test class from this mixin and call create_session in your setUp method to initialize session.

class TestMobileResumeUpload(ModifySessionMixin, TestCase):
    def setUp(self):
        ....
        self.create_session()
        ....

You can set any parameters to self.client.session now which can be accessed in your view as session variable. Also session changes done in view will be available in self.client.seesion for testing.

Atwater answered 2/8, 2015 at 3:48 Comment(4)
Happy to help. Please accept/upvote the answer if its working fine.Atwater
And I must to add some comment:Absalom
1) If I add data to session from view, I needn't to create class ModifySessionMixin(), test work's fine without it, because it's already exist in original source. 2) BUT to add data from test to session I must create class ModifySessionMixin() and there I can add some data to session (after data adding, as I understand, may be I wrong, I have to create new object -self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key): store = session_engine.SessionStore(), then store['some_key'] = some_value, then store.save().Absalom
django.utils.importlib has been removed as of Django 1.9. Instead you can just use: from importlib import import_moduleArmalla

© 2022 - 2024 — McMap. All rights reserved.