Django의 self.client.login (…)은 단위 테스트에서 작동하지 않습니다.


83

두 가지 방법으로 단위 테스트 용 사용자를 만들었습니다.

1) 대략 다음과 같은 "auth.user"에 대한 고정물을 만듭니다.

    { 
        "pk": 1, 
        "model": "auth.user", 
        "fields": { 
            "username": "homer", 
            "is_active": 1, 
            "password": 
"sha1$72cd3$4935449e2cd7efb8b3723fb9958fe3bb100a30f2", 
            ... 
        } 
    }

겉보기에는 중요하지 않은 부분은 생략했습니다.

2) setUp 함수에서 'create_user'를 사용합니다 (비록 모든 것을 조명기 클래스에 보관하고 싶지만) :

def setUp(self): 
       User.objects.create_user('homer', 'ho...@simpson.net', 'simpson') 

두 경우 모두 암호는 심슨입니다.

이 정보가 테스트 데이터베이스에 몇 번이고 올바르게로드되고 있는지 확인했습니다. User.objects.get을 사용하여 User 개체를 가져올 수 있습니다. 'check_password'를 사용하여 비밀번호가 맞는지 확인할 수 있습니다. 사용자가 활성 상태입니다.

그러나 항상 self.client.login (username = 'homer', password = 'simpson') 실패합니다. 왜 그런지 당황합니다. 나는 이것과 관련된 모든 인터넷 토론을 읽었다 고 생각합니다. 아무도 도울 수 있습니까?

내 단위 테스트의 로그인 코드는 다음과 같습니다.

    login = self.client.login(username='homer', password='simpson') 
    self.assertTrue(login) 

감사.


1
받은 오류 메시지는 무엇입니까?
zs2020 2010

테스트 케이스는 'self.assertTrue (login)'행에서 실패합니다. login () 함수는 False를 반환합니다.
thebossman 2010

1
기본적으로 두 번째 변형을 복사하여 붙여 넣었으며 Django 1.3에서 작동합니다. 수입품을 포함한 전체 코드를 게시 할 수 있습니까?
Liorsion 2011 년

이것은 내가 더 이상 액세스하지 않는 코드베이스 어딘가에 묻혔습니다. 문제가 발생하면 후속 조치를 취할 것이지만 기록을 위해 이전 버전의 Django를 사용했습니다. 1.0.2라고 생각합니다.
thebossman 2011 년

답변:


122

작동하지 않는 코드 :

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

user = User.objects.create(username='testuser', password='12345')

c = Client()
logged_in = c.login(username='testuser', password='12345')

왜 작동하지 않습니까?

위의 스 니펫에서 User를 만들 때 실제 암호 해시는로 설정됩니다 12345. 클라이언트가 login메서드를 호출하면 password인수 값은 12345해시 함수를 통해 전달되어 다음과 같은 결과가 발생합니다.

hash('12345') = 'adkfh5lkad438....'

그런 다음 데이터베이스에 저장된 해시와 비교되며 클라이언트는 액세스가 거부됩니다. 'adkfh5lkad438....' != '12345'

해결책

해야 할 적절한 일은 set_password해시 함수를 통해 주어진 문자열을 전달하고 결과를에 저장하는 함수를 호출하는 것입니다 User.password.

또한 호출 후 set_password업데이트 된 User개체를 데이터베이스에 저장해야 합니다.

user = User.objects.create(username='testuser')
user.set_password('12345')
user.save()

c = Client()
logged_in = c.login(username='testuser', password='12345')

44
당신은 사용 User.objects.create_superuser()하고 User.objects.create_user()정확히이 set_password()호출 을 수행합니다 .
vdboor

로그인하면
rocky raccoon

@vdboor 주석에 추가 : 메모를 장고 1.4도부터 것을 User.objects.get_or_create()요구되는 수행 set_password()전화
furins

53

더 쉬운 방법은 force_loginDjango 1.9의 새로운 기능 을 사용하는 것입니다 .

force_login(user, backend=None)

예를 들면 :

class LoginView(TestCase):
    def setUp(self):
        self.client.force_login(User.objects.get_or_create(username='testuser')[0])

5

아래와 같이 확인할 수 있습니까?

from django.test import TransactionTestCase, Client

class UserHistoryTest(TransactionTestCase):
    self.user = User.objects.create(username='admin', password='pass@123', email='admin@admin.com')
    self.client = Client() # May be you have missed this line

    def test_history(self):
        self.client.login(username=self.user.username, password='pass@123')
        # get_history function having login_required decorator
        response = self.client.post(reverse('get_history'), {'user_id': self.user.id})
        self.assertEqual(response.status_code, 200)

이 테스트 케이스는 저에게 효과적이었습니다.


5

확인 django.contrib.sessions에 추가됩니다 INSTALLED_APPS때문에 client.login()이 있고, 그렇지 않은 경우는 항상 false를 돌려 보낼 검사 :

https://docs.djangoproject.com/es/1.9/topics/http/sessions/#enabling-sessions


2
이것에 대해 +1. django.contrib.sessions.middleware.SessionMiddleware미들웨어 클래스 에서도 django.test.Client를 통해 로그인 할 수 없습니다. 그것은이 답변 찾기 위해 나에게 주 소요
학생

0
from django.test import TestCase
from django.contrib.auth.models import User
from django.test import Client
class MyProfile(TestCase):
    @classmethod
    def setUpClass(self):
        self.username = 'dummy' + data + '@gmail.com'
        self.password = 'Dummy@123'
        user = User.objects.create(username=self.username)
        user.set_password(self.password)
        user.save()
        c = Client()
        self.client_object = c.login(username=self.username, password=self.password)
        self.content_type = "application/json"
        response = self.client_object.post('/api/my-profile/', content_type=self.content_type)

-3

여전히 이것을 팔로우하는 사람이 있다면 성공적으로 로그인하려면 'is_staff'및 'is_active'속성이 True로 유지되어야한다고 생각합니다.

self.user = User.objects.create(username='testuser',password='pwd',is_active=1,is_staff=1)


4
이것은 방금 작동했습니다 ........... self.user = User.objects.create (username = 'testuser', password = '12345', is_active = True, is_staff = True, is_superuser = True) self. user.set_password ( 'hello') self.user.save () user = authenticate (username = 'testuser', password = 'hello') login = self.c.login (username = 'testuser', password = 'hello') ) self.assertTrue (login)
Arindam Roychowdhury

이것은 is_staff일반적으로 관리자 패널에 대한 액세스 권한이 부여되는지 여부를 정의 하는 것과 관련이 없습니다 . 보시다시피 초기 게시물의 데이터는 이미 가지고 is_active = 1있으며 User.objects.create().
jnns

1
@arindamroychowdhury - 월드 오브 워크래프트 - 사실 .. (귀하의 코멘트) 일한
리처드 드 위트

1
버전 문제 일 수 있지만 인증 호출을 주석 처리해야했습니다. 그 외에는 귀하의 의견이 챔피언처럼 작동했습니다! 추가 테스트를 통해 is_active, is_superuser 및 is_staff가 모두 불필요하다는 것을 알았습니다. 그것을 한 것은 set_password에 대한 호출이었습니다.
dolphus333
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.