TIL DAY 36 || Python Unittest on Django, How to Mock data
Kakao API 를 사용하여 requests.get 으로 사용자의 정보를 받아오는 view 를 unit test 해야했다. 하지만 unit test 는 서드파티 앱에 의존하지 않아야하고, 자체적으로 test 할 수 있어야 하기 때문에 실제로 요청을 보내면 안된다.
그래서 해당 요청을 mocking 하던 중 마주했던 어려움들을 어떻게 풀어갔는지 소개하려고 한다.
mock.patch 로 requests.get() 의 return_value 를 그냥 dict 로 했더니, 뒤에 오는 json() 에서
dict has no attribute json
라는 에러가 발생했다.
그래서 return_value 를 requests.Response() 로 바꿔보기로 했다.
Modifying requests.Response() object
with patch
requests.get 의 return_value 를
실제 requests.Response object 를 만들어 값을 변경해주는 방법을 사용했다.
왜냐면 views.py 코드에서 requests.get 의 attribute 인 json() 까지 mocking 해 줄 생각을 못했었기 때문이다.
어쨌든 그 생각을 하기 전에는 다음과 같은 과정을 거쳐서 문제를 해결했다.
실제로 requests.Response() 객체를 만든 뒤
._content
attribute 에
mock_content dictionary type 객체를
bytes 객체로 변환해주면
requests.Response.json() 의 값이 dictionary type 의 mock_content 가 된다.
--> 이렇게 했을 때는 쓸데없이 실제 object 를 만들어서 조작해야되기 떄문에 1. 귀찮고 2. 그만큼 메모리를 낭비하게 된다.
다음 방법을 보자.
patch decorator
실제로 requests.Response() 객체 자체를 만들지 않고, requests.get.json() 자체의 return_value 를 mocking 하는 아주 간단한 방법이 있었다.
-
mocking 할 모듈을 patch 데코레이터 인자로 넘겨줌
-
함수의 파라미터로 데코레이터 인자로 넘겨받은 mocking 할 모듈 object를 받음
이 때 넘겨받은 인자를 print 해보면 name 이 get 인 MagicMock object 라는 것을 알 수 있다.
<MagicMock name='get' id='140646286606096'>
-
MagicMock object 의 return_value 값을 response 에 할당한다.
이 때 response 를 print 해보면 name 이 get() 인 MagicMock object 로 변했다.
<MagicMock name='get()' id='140369968892704'>
get 과 get() 의 차이다.
get 은 모듈 자체이고 get() 은 object 이다.
-
print(mocked_request.json.return_value)
를 해보면
<MagicMock name='get.json()' id='140564181636624'>
-
print(mocked_request.return_value.json.return_value
를 해보면
<MagicMock name='get().json()' id='140260556133904'>
우리가 mocking 해야 할 instance 는 다음과 같다.
response = requests.get(KAKAO_USERINFO_REQUEST_URL, headers=headers).json()
간략히 나타내면
requests.get().json() 이고, 이를 풀어보면
requests.Response().json() 이 된다.
설명이 길었지만, 핵심은
wrong way
이 방법이 아니라
response = mocked_request
response.json.return_value = mock_content
right way
이 방법으로 해주어야 한다는 것이다.
response = mocked_request.return_value
response.json.return_value = mock_content
이렇게 하면 성공적으로 mocking 이 된다.
Author And Source
이 문제에 관하여(TIL DAY 36 || Python Unittest on Django, How to Mock data), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@tk_kim/TIL-DAY-33-Python-Unittest-on-Django-How-to-Mock-data저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)