본문 바로가기

PYTHON/Django

[Django] 클린 코스를 위한 테스트 주도개발 5장

현재 내가 사용하고 있는 Django의 버전이 책에서 사용하고 있는 버전과 달라서 오류가 발생했다.

 

바로 render_to_string 함수와 csrf_token 문제인데....

 

혹시 누군가 나와 똑같은 삽질(?)을 하고 있다면 이 글이 도움이 되길 바란다.

 

 

책의 버전은 render_to_string 함수를 사용하더라도 csrf_token 이 제대로 작동(?)된채로 값을 불러오고 저장할 수 있는데

 

지금 내가 사용하고 있는 버전에선 render_to_string 함수를 사용하면 csrf_token가 제대로 작동되지 않은채로 값이 불러와진다.

 

이 문제 때문에 마지막 assertEqual 부분에서 테스트코드가 계속 통과하지 못했다.

 

 

를 참고하여 해결 할 수 있었다.

 

render_to_string의 마지막 인자에 request = request 를 추가해주면 된다는데 이 방법은 csrf_token 자체는 동작하지만 결과적으로 value 값이 다르게 나온다. 

 

1
2
<input type="hidden" name="csrfmiddlewaretoken" value="eB336gEtVp6Z5ubs9Tys0ZY6 />
<input type="hidden" name="csrfmiddlewaretoken" value="jixuiEZet7INyVPUvWELTlmj />
cs

 

이런식으로?..

 

 

그래서 csrf 를 전부 날려버는 방법을 선택했다..

이건 여기를 참고했다.

 

사실 이 방법이 맞는건지 모르겠지만 어쨋든 진도는 나가야 했기 때문에 임시방편으로 해결을 해야했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from django.urls import resolve
from django.test import TestCase
from django.http import HttpRequest
from django.template.loader import render_to_string
import re
 
from lists.views import home_page
 
# Create your tests here.
 
 
class HomePageTest(TestCase):
    def remove_csrf(self, origin):
        csrf_regex = r'<input[^>]+csrfmiddlewaretoken[^>]+>'
        return re.sub(csrf_regex, '', origin)
 
    def test_root_url_resolves_to_home_page_view(self):
        found = resolve('/')
        self.assertEqual(found.func, home_page)
 
 
    def test_home_page_returns_correct_html(self):
        request = HttpRequest()
        request.method = 'POST'
        request.POST['item_text'= '신규 작업 아이템'
 
        response = home_page(request)
 
        self.assertIn('신규 작업 아이템', response.content.decode())
        expected_html = self.remove_csrf(render_to_string(
            'home.html',
            {'new_item_text''신규 작업 아이템'},
            request=request
        ))
        response_decode = self.remove_csrf(response.content.decode())
        self.assertEqual(response_decode, expected_html)
cs

 

이 코드로 실행하면 아마 테스트를 깔끔하게 통과 할 수 있을것이다.