login() in Django testing framework

前端 未结 3 501
感动是毒
感动是毒 2021-02-01 02:15

I have started using Django\'s testing framework, and everything was working fine until I started testing authenticated pages.

For the sake of simplicity, let\'s say tha

相关标签:
3条回答
  • 2021-02-01 02:43

    It can often be useful to use a custom auth backend that bypassess any sort of authentication during testing:

    from django.contrib.auth import get_user_model
    
    class TestcaseUserBackend(object):
        def authenticate(self, testcase_user=None):
            return testcase_user
    
        def get_user(self, user_id):
            User = get_user_model()
            return User.objects.get(pk=user_id)
    

    Then, during tests, add yourapp.auth_backends.TestcaseUserBackend to your AUTHENTICATION_BACKENDS:

    AUTHENTICATION_BACKENDS = [
        "akindi.testing.auth_backends.TestcaseUserBackend",
    ]
    

    Then, during tests, you can simply call:

    from django.contrib.auth import login
    user = User.objects.get(…)
    login(testcase_user=user)
    
    0 讨论(0)
  • 2021-02-01 02:43

    Token based authentication: I was in same situation. I found solution in which actually I did generate a user for login purpose in setUp method. Then later in the test methods, I tried to get the token and passed it along with request data.

    setUp:

    1. create a user
    self.pravesh = User.objects.create(
         email='psj.aaabbb@gmail.com',
         first_name='Pravesh',
         last_name='aaabbb',
         phone='5456165156',
         phonecountrycode='91'
    )
    
    1. set password for the user
    self.password = 'example password'
    self.pravesh.set_password(self.password)
    

    test_method:

    1. create client
    client.login(email=self.pravesh.email, password=self.password)
    
    1. get token (in case of token auth)
    token = Token.objects.create(user=self.pravesh)
    
    1. pass login information
    response = client.post(
        reverse('account:post-data'),
        data = json.dumps(self.data),
        HTTP_AUTHORIZATION='Token {}'.format(token),
        content_type = 'application/json'
    )
    
    0 讨论(0)
  • 2021-02-01 02:53

    The problem is that you're not passing RequestContext to your template.

    Also, you probably should use the login_required decorator and the client built in the TestCase class.

    I'd rewrite it like this:

    #views.py
    from django.contrib.auth.decorators import login_required
    from django.shortcuts import render
    from django.contrib.auth import get_user_model
    
    @login_required(login_url='/users/login')
    def secure(request):
        user = request.user
        return render(request, 'secure.html', {'email': user.email})
    
    
    
    #tests.py
    class SimpleTest(TestCase):
        def setUp(self):
            User = get_user_model()
            user = User.objects.create_user('temporary', 'temporary@gmail.com', 'temporary')
    
        def test_secure_page(self):
            User = get_user_model()
            self.client.login(username='temporary', password='temporary')
            response = self.client.get('/manufacturers/', follow=True)
            user = User.objects.get(username='temporary')
            self.assertEqual(response.context['email'], 'temporary@gmail.com')
    
    0 讨论(0)
提交回复
热议问题