2011-04-14 50 views
39

如何在提交註冊表單後測試用戶是否已登錄?測試用戶是否已成功登錄

我嘗試了以下方法,但即使在將登錄邏輯添加到我的註冊視圖之前,它也會返回True

def test_that_user_gets_logged_in(self): 
    response = self.client.post(reverse('auth-registration'), 
           { 'username':'foo', 
            'password1':'bar', 
            'password2':'bar' }) 

    user = User.objects.get(username='foo') 
    assert user.is_authenticated() 

多數民衆贊成被測試代碼:

class RegistrationView(CreateView): 
    template_name = 'auth/registration.html' 
    form_class = UserCreationForm 
    success_url = '/' 

    def auth_login(self, request, username, password): 
     ''' 
     Authenticate always needs to be called before login because it 
     adds which backend did the authentication which is required by login. 
     ''' 

     user = authenticate(username=username, password=password) 
     login(request, user) 

    def form_valid(self, form): 
     ''' 
     Overwrite form_valid to login. 
     ''' 

     #save the user 
     response = super(RegistrationView, self).form_valid(form) 

     #Get the user creditials 
     username = form.cleaned_data['username'] 
     password = form.cleaned_data['password1'] 

     #authenticate and login 
     self.auth_login(self.request, username, password) 

     return response 
+0

您是否嘗試過'response.request.user.is_authenticated()'? – 2011-04-14 09:29:01

+0

我做了但請求對象沒有用戶對象。 – Pickels 2011-04-14 09:34:26

回答

62

這不是最好的答案。見https://stackoverflow.com/a/35871564/307511

Chronial給 如何使下面這種說法一個很好的例子。他的回答 比我現在的代碼更好。


最簡單的方法來測試用戶是否登錄是通過測試客戶端對象:

self.assertIn('_auth_user_id', self.client.session) 

你也可以檢查是否有特定的用戶登錄

self.assertEqual(int(self.client.session['_auth_user_id']), user.pk) 

作爲附加信息,response.request對象不是HttpRequest對象;相反,它是一個普通的字典,其中包含有關實際請求的一些信息,因此無論如何它都不具有user屬性。

此外,測試response.context對象並不安全,因爲您沒有上下文。

+10

正如一個額外的保證,你可以做同樣的測試,但使用'SESSION_KEY'變量的值。就像這樣: '從django.contrib.auth進口SESSION_KEY' 'self.assertTrue(在self.client.session SESSION_KEY)' 你可以看到這是在身份驗證的應用程序應用於Django框架:[github上。 ..test/views.py](https://github.com/django/django/blob/master/django/contrib/auth/tests/views.py#L51) 他們也有一個方便的功能來測試用戶已註銷:[github ... test/views.py](https://github.com/django/django/blob/master/django/contrib/auth/tests/views.py#L429) – bobc 2013-02-19 18:22:06

+0

謝謝爲了補充,我沒有意識到這一點。 :) – emyller 2013-02-19 20:49:53

+2

第一條評論鏈接被破壞 - 這是它現在託管的位置 - https://github.com/django/django-old/blob/master/django/contrib/auth/tests/views.py – 2014-05-17 09:49:26

5

User模型總是返回True方法is_authenticated()。在request.userAnonymousUser的實例的情況下,False返回request.user.is_authenticated()is_authenticated()方法總是返回False。 雖然測試,你可以看看response.context['request'].user.is_authenticated()

您也可以嘗試在測試這需要登錄才能訪問另一個頁面,看看是否response.status回報200302(從login_required重定向)。

+0

什麼可能是我沒有response.request.user對象的原因?這是請求字典看起來像{'CONTENT_LENGTH':244,'wsgi.input':,'REQUEST_METHOD':'POST','PATH_INFO':'/ register/','CONTENT_TYPE':'multipart/form-data; border = BoUnDaRyStRiNg','QUERY_STRING':''} – Pickels 2011-04-14 09:42:37

+0

我添加了我正在測試的代碼。 – Pickels 2011-04-14 09:46:53

+0

你使用的是'django.contrib.auth.middleware.AuthenticationMiddleware'嗎? – 2011-04-14 09:47:46

1

你在哪裏初始化你的self.client?你的setUp方法還有什麼?我有一個類似的測試,你的代碼應該可以正常工作。下面是我如何做到這一點:

from django.contrib.auth.models import User 
from django.test import TestCase 
from django.test.client import Client 


class UserTestCase(TestCase): 

    def setUp(self): 
     self.client = Client() 

    def testLogin(self): 
     print User.objects.all() # returns [] 
     response = self.client.post(reverse('auth-registration'), 
          { 'username':'foo', 
           'password1':'bar', 
           'password2':'bar' }) 
     print User.objects.all() # returns one user 
     print User.objects.all()[0].is_authenticated() # returns True 

編輯

如果我註釋掉我的登錄邏輯,我不self.client.post(後得到任何用戶。如果您確實想檢查用戶是否已通過身份驗證,請使用self.client訪問需要用戶身份驗證的另一個網址。從上面的,獲得持續的另一頁:

response = self.client.get(reverse('another-page-which-requires-authentication')) 
print response.status_code 

上面應該返回200,以確認用戶身份驗證。除此之外,它將使用302代碼重定向到登錄頁面。

+2

print User.objects.all()[0] .is_authenticated()是否在實現登錄邏輯之前嘗試測試它?因爲我從其他人所說的內容中瞭解到,這將始終迴歸真實。你需要request.user.is_authenticated。此外,django TestCase附帶一個已經初始化的Client對象,因此不需要這樣做兩次。 – Pickels 2011-04-14 15:00:56

+0

查看編輯答案。 – 2011-04-14 15:30:01

8

Django的TestClient的有login method如果用戶成功登錄返回true。

+2

除了不是進行login()調用的測試。 – Manur 2013-11-14 17:01:33

37

可以使用auth模塊的get_user方法。它表示它想要一個請求作爲參數,但它只使用請求的session屬性。而且恰巧我們的Client有這個屬性。

from django.contrib import auth 
user = auth.get_user(self.client) 
assert user.is_authenticated() 
+0

你確定它會在測試用例上下文中工作嗎? – emyller 2016-03-09 18:19:45

+0

那麼,這就是我使用它:) – Chronial 2016-03-09 23:44:35

+0

+1這是一個很好的答案,並會做出有用的斷言:https://gist.github.com/bengolder/c9dc7006f9d6b4d17d5af5465115df73 – BenjaminGolder 2016-05-28 03:57:01

0

還有另一種簡潔的方式,使用在wsgi_requestresponse

response = self.client.post('/signup', data) 
assert response.wsgi_request.user.is_authenticated() 

和@Chronial的方式也可提供wsgi_request

from django.contrib import auth 
user = auth.get_user(response.wsgi_request) 
assert user.is_authenticated() 

因爲response.wsgi_request對象具有session屬性。我覺得使用response.wsgi_request.user更簡單。