TIL/Python

TIL.88 Decorator(토큰 인가)_Unit Test

codermun 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
반응형