import json
import re
import bcrypt
import jwt
import unittest
from django.test import TestCase
from django.test import Client
from unittest.mock import (
patch,
MagicMock
)
from .models import (
Account,
Gender
)
class SignUpTest(TestCase):
def setUp(self):
Gender(
id =1,
name = "male"
).save()
Account(
name = "홍길동",
password = bcrypt.hashpw('p1234'.encode('utf-8'), bcrypt.gensalt()).decode('utf-8'),
birthdate = "19880705",
gender = Gender.objects.get(name="male"),
phone_number = "01012345678",
user_email = "test@gmail.com"
).save()
def tearDown(self):
Account.objects.all().delete()
Gender.objects.all().delete()
def test_signup_success(self):
client = Client()
account = {
"name" : "이순신",
"password" : "p1234",
"birthdate" : "19330303",
"gender" : "male",
"phone_number" : "01043215678",
"user_email" : "test1@naver.com"
}
response = client.post("/account/sign-up", json.dumps(account), content_type = "application/json")
self.assertEqual(response.status_code, 200)
def test_signup_exists_email(self):
client = Client()
account = {
"name" : "장보고",
"password" : "p1234",
"birthdate" : "19330303",
"gender" : "male",
"phone_number" : "01011112222",
"user_email" : "test@gmail.com"
}
response = client.post("/account/sign-up", json.dumps(account), content_type = "application/json")
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {"message" : "ALREADY_EXISTS"})
def test_signup_key_error(self):
client = Client()
account = {
"id" : "장보고",
"password" : "p1234",
"birthdate" : "19330303",
"gender" : "male",
"phone_number" : "01011112222",
"user_email" : "test2@gmail.com"
}
response = client.post("/account/sign-up", json.dumps(account), content_type = "application/json")
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {"message" : "INVALID_KEYS"})
class SignInTest(TestCase):
def setUp(self):
Gender(
id =1,
name = "male"
).save()
Account(
name = "홍길동",
password = bcrypt.hashpw('p1234'.encode('utf-8'), bcrypt.gensalt()).decode('utf-8'),
birthdate = "19880705",
gender = Gender.objects.get(name="male"),
phone_number = "01012345678",
user_email = "test@gmail.com"
).save()
def tearDown(self):
Account.objects.all().delete()
Gender.objects.all().delete()
def test_signin_success(self):
client = Client()
account = {
"password" : "p1234",
"user_email" : "test@gmail.com"
}
response = client.post("/account/sign-in", json.dumps(account), content_type = "application/json")
self.assertEqual(response.status_code, 200)
def test_signin_wrong_password(self):
client = Client()
account = {
"password" : "p12345",
"user_email" : "test@gmail.com"
}
response = client.post("/account/sign-in", json.dumps(account), content_type = "application/json")
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {"message" : "WRONG_PASSWORD"})
def test_signin_not_exist_email(self):
client = Client()
account = {
"password" : "p1234",
"user_email" : "test11@gmail.com"
}
response = client.post("/account/sign-in", json.dumps(account), content_type = "application/json")
self.assertEqual(response.status_code, 401)
self.assertEqual(response.json(), {"message" : "NOT_EXIST_EMAIL"})
def test_signin_key_error(self):
client = Client()
account = {
"password" : "p1234",
"user_id" : "test@gmail.com"
}
response = client.post("/account/sign-in", json.dumps(account), content_type = "application/json")
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {"message" : "INVALID_KEYS"})
class KakaoLoginTest(TestCase):
def setUp(self):
Gender(
id =1,
name = "male"
).save()
Account(
name = "홍길동",
password = bcrypt.hashpw('p1234'.encode('utf-8'), bcrypt.gensalt()).decode('utf-8'),
birthdate = "19880705",
gender = Gender.objects.get(name="male"),
phone_number = "01012345678",
user_email = "test@gmail.com"
).save()
@patch('account.views.requests')
def test_kakao_signin_success(self, mocked_request):
class FakeResponse:
def json(self):
return {
"id" : 12345,
"properties" : {"nickname": "test_user"},
"kakao_account" : {"email":"test@gmail.com","gender":"male","birthday":"18000908"}
}
mocked_request.get = MagicMock(return_value = FakeResponse())
client = Client()
header = {'HTTP_Authorization':'fake_token.1234'}
response = client.post('/account/kakao-login', content_type='applications/json', **header)
self.assertEqual(response.status_code, 200)
@patch('account.views.requests')
def test_kakao_signin_keyerror(self, mocked_request):
class FakeResponse:
def json(self):
return {
"id" : 12345,
"properties" : {"username": "test_user"},
"kakao_account" : {"email":"test@gmail.com","gender":"male","birthday":"18000908"}
}
mocked_request.get = MagicMock(return_value = FakeResponse())
client = Client()
header = {'HTTP_Authorization':'fake_token.1234'}
response = client.post('/account/kakao-login', content_type='applications/json', **header)
self.assertEqual(response.status_code, 400)
if __name__ == '__main__':
unittest.main()
이번 프로젝트에서 가장 힘들었던 부분이다.
unittest에 대한 중요성은 이해가 되었지만 어떻게 구현할지 막막하게 다가왔다. 내가 구현한 기능들을 어떤 방식으로 test 할지 코드를 어떻게 시작해야 할지 망설였다.
그리고 현재 DB에 저장된 데이터와 setup을 통해 만드는 데이터가 헷갈렸다.
하지만 setup을 통해 해당 unittest를 위한 객체를 만들고 기능은 views.py에 내가 구현한 함수를 사용한다는 내용을 이해하고 tests.py 코드 작성을 시작할 수 있었다.
일반 회원의 경우 test를 완성하였지만 kakao_login의 test에서 다시 한번 막혔다.
먼저 kakao 측에서 주는 토큰 값, 데이터 값들을 어떻게 tests.py에서 구현할지 생각이 떠오르지 않았다. 그래서 postman으로 로그인 test를 해서 얻은 토큰 값을 사용해보기도 하였다. 하지만 생각처럼 되지 않아 계속 고민하였다.
해결이 되지 않아 검색을 계속하던 중 다른 분의 예제를 보았는데 Patch와 MagicMock을 사용하여 test를 진행하는 것을 봤다.(https://velog.io/@devzunky/TIL-no.86-Python-Django-Kakao-Social-Login-Unit-Test)
patch 데코레이터를 통해 account.views.requests 모듈을 흉내(MagicMock)를 낸다. 이를 통해 views.py에서 사용하는 requests를 흉내 낸다.
kakao API를 실제로 호출하지 않고 흉내를 내고 return값 역시 내가 임의로 설정을 해준다.
이를 통해 값을 비교하고 test를 진행한다.