Post method test code [20211003]

Jungsoo kim·2021년 10월 3일
0

wecode

목록 보기
30/30

  이번에는 Post method와 관련하여 test code를 어떻게 작성하는지에 대해 간단하게 알아보려고 한다. 이번 2차 프로젝트에서는 모든 get, post method에 관련하여 테스트 코드를 작성하였는데, post method가 비교적 나에게는 어렵게 다가와서 이렇게 글을 작성하게 되었다.

<목차>
1. 구현 기능
2. test code
3. 작동 로직

1. 구현 기능

이번에 알아보고자 하는 test 코드에 해당하는 구현 기능은 아래와 같다.

위 사진을 보게되면 출금하기 버튼이 있는 것을 확인할 수 있다. 예치금으로 있는 금액을 출금하는 기능인데, 이 기능을 나는 Post method로 구현하였다. 따라서 해당 기능에 대한 test code가 필요하였다.

2. Code

내가 작성한 기능 code와 test code는 아래와 같다.

# views.py

class WithdrawalView(View):
    @login_decorator
    def post(self, request):
        try:
            data = json.loads(request.body)
            deposit = request.user.deposit

            if data["amounts"] <= 0:
                return JsonResponse({"message": "INVALID_INPUT"}, status=400)

            if data["amounts"] > deposit.balance:
                return JsonResponse({"message": "WRONG_REQUEST"}, status=400)

            with transaction.atomic():
                Transaction.objects.create(
                    type_id=TransactionType.Type.WITHDRAWAL.value,
                    information=Bank.objects.get(id=deposit.withdrawal_bank.id).name,
                    amounts=data["amounts"],
                    deposit=deposit,
                    user=request.user,
                )

                deposit.balance -= data["amounts"]
                deposit.save()

            return JsonResponse(
                {"message": "SUCCESS", "deposit_balance": deposit.balance}, status=201
            )

        except TypeError:
            return JsonResponse({"message": "TYPE_ERROR"}, status=400)

        except KeyError:
            return JsonResponse({"message": "KEY_ERROR"}, status=400)
#tests.py
class WithdrawalTest(TestCase):
    def setUp(self):
        TransactionType.objects.create(id=3, name="출금")

        Bank.objects.create(id=2, name="농협은행")

        Deposit.objects.create(
            id=1,
            withdrawal_account="111-222-333",
            withdrawal_bank_id=2,
            deposit_account="444-555-666",
            deposit_bank_id=2,
            balance=300000,
        )

        User.objects.create(
            id=2,
            name="무현",
            email="example@naver.com",
            phone_number="010-2222-4444",
            password="1234dfsdflker@!",
            deposit_id=1,
        )

    def tearDown(self):
        User.objects.all().delete()
        Deposit.objects.all().delete()
        Bank.objects.all().delete()
        TransactionType.objects.all().delete()

    def test_withdrawal_post_success(self):
        client = Client()
        deposit_amounts = {"amounts": 100000}
        header = {
            "HTTP_Authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mn0.G9SKGv3338DXgNWbuVLZ8n3NZHHbo8VQtr3lp_8UfFg"
        }
        response = client.post(
            "/transactions/withdrawal",
            json.dumps(deposit_amounts),
            content_type="application/json",
            **header
        )
        self.assertEqual(response.status_code, 201)

    def test_withdrawal_post_invalid_input(self):
        client = Client()
        deposit_amounts = {"amounts": -100000}
        header = {
            "HTTP_Authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mn0.G9SKGv3338DXgNWbuVLZ8n3NZHHbo8VQtr3lp_8UfFg"
        }
        response = client.post(
            "/transactions/withdrawal",
            json.dumps(deposit_amounts),
            content_type="application/json",
            **header
        )
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.json(), {"message": "INVALID_INPUT"})

기능에 대한 코드는 따로 로직 설명을 하지 않으려고 한다. 이번 글의 목적은 test code의 로직에 대한 것이 주요 목적이기 때문이다. 그렇게 어려운 코드가 아니기 때문에, 천천히 읽어보면 충분히 이해할 수 있을 거라 생각한다.

내가 Post method의 test code를 비교적 어렵게 생각했었던 것 중 하나가 header에 들어있는 token 때문이었다. 물론 get method에서도 token이 필요할 경우가 있지만, 내가 구현했던 기능에는 token이 필요한 경우가 없었다. 따라서 token이 있을 경우에 post method에 대한 test code의 로직을 알아보려고 한다.

3. 작동 로직

  test code를 보게되면 크게 3가지로 나뉜다. 데이터를 만들어주는 함수, 데이터를 지워주는 함수, 로직 확인하는 함수 이다.
위에 첨부한 코드중에 로직 확인하는 함수는 test_withdrawal_post_success, test_withdrawal_post_invalid_input 이다.

작동 로직은 아래와 같다.

  1. 함수를 정의하고 변수를 설정해 준다.
    이번의 경우에는 Django의 내장 함수 client가 필요하기 때문에 client 변수에 Client()함수를 할당해 준다. 또한, Post method를 통해 입력 받게 되는 값을 변수 설정 해주고 마지막으로 header 변수를 설정해 줘야 한다. (header의 경우에는 딕셔너리 형태로 해줘야 한다.)
  2. 그 다음 response 변수에 post를 통해 받게되는 값을 설정해준다.
    첫 번째로, endpoint, 두 번째로는 입력되는 데이터의 값을 json형태로 변형하여 받아온다. 마지막으로 header에 할당되어 있는 token 값을 가져온다.
  3. 받아온 값과 Post method를 통해 입력된 값이 맞는지 확인 한다.

token 값과 관련하여 하나 추가로 얘기할 것이 있다.
내가 위의 적은 토큰 코드는 id 값이 2인 임의의 토큰을 사용하였다. 그 이유는 내가 테스트 코드에서 만들어준 유저의 id값이 2이기 때문이다. 즉, 토큰을 다시 디코드해서 해싱하였을 때 id 값이 2가 나오는 토큰이면 아무런 토큰이나 사용해도 된다. 우리는 id 값이 테스트 코드에서 입력되어 있는 유저의 id 값과 일치하기만 하면 되기 때문이다.

즉, 이번 글에서 강조하고 싶은 것이 두 가지가 있는데 아래와 같다.

  1. token이 있는 경우에는 header 변수에 딕셔너리 형태로 token 값을 설정해줘야 한다.
  2. 사용하는 token은 decoding 해서 되돌렸을 때 id 값이 테스트 코드의 유저 id 값과 일치하면 된다는 것이다.

나의 경우에는 이 방식을 알지 못해 test code를 짜는데 진짜 수 시간을 잡아 먹었다. 그렇기 때문에 누군가에게는 이 글이 도움이 되길 바라며 글을 마치겠다. 그럼 이만...~

profile
어렵지만 꾸준히 차근차근 해 나가자~!

0개의 댓글