Unittest시 다중 요청 mock처리

Hyeon Soo·2021년 4월 4일
0

본래 unittest를 진행함에 있어서, 외부 서버로 요청을 보내는 view를 test할 때는 @patch를 통해 실제로 요청이 진행되지 않고 단독적으로 실행되도록 해주어야 한다. 이때, 서로 다른 method로 요청을 보내는 경우이면 @patch를 여러번 사용하는 방식으로 각 요청을 처리해줄 수 있으나, 같은 method로 여러번의 요청을 보내는 경우, @patch는 한번인데 처리해주어야 하는 응답은 여러개가 필요하다. 이 경우 어떻게 해야하는지 적어보고자 한다.

외부 서버로 요청을 보내는 view를 test할 때는 @patch를 사용한 후 response를 객체 형식으로 임의 작성하여 magicmock에 넣어주어 요청이 실행되지 않도록 해야한다. 예를 들자면

@patch(app.views.method)
class response:
	def json(self):
    	return ~~~

mock_response.method = MagicMock(return_value=response())

의 방식이다. 만약 요청을 보내는 다른 method가 있다면, @pathck를 추가해주고, 다른 response를 생성해주면 된다.

하지만 만약 같은 method를 이용하여 여러번의 요청을 보낸다면, 위의 방식으로는 동작하지 않을 것이다. 예를 들어 views.py가

response1 = requests.request(~~~)
response2 = requests.request(~~~)
response3 = requests.request(~~~)

으로 3번의 요청에 각각 다른 응답을 받는다면, 앞서 적었던 방식으로는 하나의 응답만 mock처리하여 줄 수 있기 때문에, test를 할 때 하나의 응답만 대체된다.

이를 해결하기 위해선, MagicMock의 return_value를 이용하는 것이 아닌, side_effect를 이용해줄 필요가 있다. side_effect는 list안의 대체 응답 객체들을 차례대로 사용하여 덮어써주는 역할을 한다.

class response1:
	def json(self):
    	return ~~~
class response2:
	def json(self):
    	return ~~~
class response3:
	def json(self):
    	return ~~~

mock_request.request = MagicMock(side_effect = [response1(), response2(), response3()]

이와 같이 작성하면, 상술한 view에 차례대로 응답이 들어간다.

  • 위에선 응답 객체를 일일히 작성해주었지만, 필요한 경우 객체를 반환하는 method 혹은 함수, class를 지정하여주어도 test는 동작한다. 예를 들어,
response = JsonResponse({}, status=200})

또한 동작한다.

0개의 댓글