2

I am trying to test django.contrib.auth-based user signup view with django-nose, where an activation link is being sent to a new user:

def signup(request):
    if request.method == 'POST':
        user_form = SignUpForm(request.POST)
        profile_form = ProfileForm(request.POST)
        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save(commit=False)
            user.is_active = False
            user.save()

            user.profile.user_type = profile_form['user_type'].data
            user.save()

            current_site = get_current_site(request)
            subject = 'activation email'
            message = render_to_string('registration/account_activation_email.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': account_activation_token.make_token(user),
            })
            user.email_user(subject, message)
            return redirect('account_activation_sent')
    else:
        user_form = SignUpForm()
        profile_form = ProfileForm()
    return render(request, 'registration/signup.html', {
        'user_form': user_form,
        'profile_form': profile_form
    })

Currently I use Django built-in email back-end, so that activation email is being sent to the server terminal.

I want to test the activation view which requires uid and token. Is there any way to access the email sent to the user? Is there any other way to test that?

Regenerating token in the test does not work, because hash value is generated using timestamp.

Laurynas Tamulevičius
  • 1,479
  • 1
  • 11
  • 25
  • What's EMAIL_BACKEND value in your settings ? – user2021091 Nov 29 '17 at 10:35
  • It's EMAIL_BACKEND ='django.core.mail.backends.console.EmailBackend' – Laurynas Tamulevičius Nov 29 '17 at 10:45
  • Well then if your email is sent it'll be print in your console. – user2021091 Nov 29 '17 at 10:47
  • Yes I know, but how do I access it programmatically from my unit test? – Laurynas Tamulevičius Nov 29 '17 at 10:52
  • 2
    See [this example in the docs](https://docs.djangoproject.com/en/1.11/topics/testing/tools/#email-services) or [this question](https://stackoverflow.com/questions/35364161/how-to-test-send-mail-in-django). – Alasdair Nov 29 '17 at 10:58
  • @Alasdair Thanks for sorting this one out! Interestingly enough, if I do `from django.core.mail import outbox` in the test, the outbox is empty, but if I import it this way `from django.core import mail` everything works as expected. – Laurynas Tamulevičius Nov 29 '17 at 11:37
  • 1
    The import that works, `from django.core import mail`, is the documented way to do it. `mail.outbox` is simply a list. If you import `outbox` directly, then you have a reference to the list at that point. If Django assigns a new list to `mail.outbox`, your variable still references the old list. – Alasdair Nov 29 '17 at 11:55
  • Same problem here. How did you fix the tests ? – DrGeneral Aug 04 '19 at 10:52

0 Answers0