ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL.88 Decorator(토큰 인가)_Unit Test
    TIL/Python 2021. 1. 4. 16:35
    728x90

    유닛 테스트를 작성하다 보면 토큰 인가를 구현하여

    우리 서비스에 대한 접근을 허가하고자 할때 utils.py를 이용한 토큰 인가를 데코레이터로서 활용한다.

    이를 이용해 유료/무료 서비스 가입자 인지, 우리 서비스를 이용하고 있는 회원이 맞는지 등을 토큰을 이용해 검증하고 그에 맞는 접근 권한을 부여한다.

     

    그럼 유닛테스트에서는 이를 어떻게 구현 할 수 있을까?

    정답은 없고 다양한 방법이 있겠지만 두 가지 방법을 알아보도록 하자.

    1. setUp에 토큰을 생성하고 setUp 메서드를 활용하는 방법

    (추가로 아래와 같은 오류가 날때는 setUp의 테이블 id를 생성하거나 지워보자

    id값을 기본적으로 추가할때마다 자동으로 올라가는점을 잊지말자)

    django.db.utils.IntegrityError: (1062, "Duplicate entry '1' for key 'users.PRIMARY'")
    class PassengerInformationTest(TestCase):
      def setUp(self):
            self.client     = Client()
            self.maxDiff    = None
            self.gender     = Gender.objects.create(name='male')
            self.country    = Country.objects.create(name='대한민국')
    
            hashed_password = bcrypt.hashpw('123456aA!'.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
    
            User.objects.create(
                     korean_name   = '문타리',
                     english_name  = 'munshee',
                     email         = 'munshee@naver.com',
                     password      = hashed_password,
                     date_of_birth = '19920424',
                     phone_number  = '01010101234',
                     gender_id     = self.gender.id,
                     country_id    = self.country.id
                     )
    
            payload      = {'user-id' : 1, 'exp' : datetime.now() +timedelta(hours=1)}
            access_token = jwt.encode(payload, SECRET_KEY, algorithm=JWT_ALGORITHM)
            print(access_token)
            return access_token
            
      def teatDown(self):
            Gender.objects.all().delete()
            Country.objects.all().delete()
            User.objects.all().delete()
            
      def test_flight_get_passenger_information_success(self):
            header = {'HTTP_Authorization' : self.setUp()}
            response = self.client.get('/flight/passenger', content_type='application/json', **header)
    
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.json(),
                    {
                        'USER_INFORMATION' : {
                            'country'       : '대한민국',
                            'date_of_birth' : '19920424',
                            'email'         : 'munshee@naver.com',
                            'gender'        : 'male',
                            'name'          : '문타리',
                            'phone_number'  : '01010101234'
                            }
                    })

    2. setUp에 토큰을 생성하지 않고 Client를 이용해 실제 로그인을 진행,

    그에 따라 반환되는 Token을 넘겨받아 사용하는 방법

    class PassengerInformationTest(TestCase):
      def setUp(self):
            self.client     = Client()
            self.maxDiff    = None
            self.gender     = Gender.objects.create(name='male')
            self.country    = Country.objects.create(name='대한민국')
    
            hashed_password = bcrypt.hashpw('123456aA!'.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
    
            User.objects.create(
                     id            = 1,
                     korean_name   = '문타리',
                     english_name  = 'munshee',
                     email         = 'munshee@naver.com',
                     password      = hashed_password,
                     date_of_birth = '19920424',
                     phone_number  = '01010101234',
                     gender_id     = self.gender.id,
                     country_id    = self.country.id
                     )
                     
      def teatDown(self):
            Gender.objects.all().delete()
            Country.objects.all().delete()
            User.objects.all().delete()
    
      def test_flight_get_passenger_information_success(self):
            signin_user = {
                    'email' : 'munshee@naver.com',
                    'password' : '123456aA!'
                    }
            signin_response = self.client.post('/user/signin', json.dumps(signin_user), content_type='application/json')
    
            header = {'HTTP_Authorization' : signin_response.json()['access_token']}
            response = self.client.get('/flight/passenger', content_type='application/json', **header)
    
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.json(),
                    {
                        'USER_INFORMATION' : {
                            'country'       : '대한민국',
                            'date_of_birth' : '19920424',
                            'email'         : 'munshee@naver.com',
                            'gender'        : 'male',
                            'name'          : '문타리',
                            'phone_number'  : '01010101234'
                            }
                    })

     

    Test method 안에서는 response를 몇번 하든 상관없음!!

    728x90
Designed by Tistory.