본래 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에 차례대로 응답이 들어간다.
response = JsonResponse({}, status=200})
또한 동작한다.