[파이썬] unittest 외부 서비스를 mock으로 대체하기

코드를 작성하다보면 종종 외부 서비스와의 상호작용이 필요할 때가 있습니다. 이러한 상황에서 단위 테스트를 작성하려면 외부 서비스에 대한 의존성을 가지지 않도록 해야합니다. 이를 위해 mocking이란 개념을 사용할 수 있습니다.

Mocking은 테스트 중에 외부 서비스를 모방하여 가상으로 구현한 객체를 사용하는 것을 의미합니다. 이렇게 하면 외부 서비스에 실제로 연결하지 않아도 동일한 결과를 얻을 수 있습니다. 이렇게 해서 코드와 테스트의 결합도를 낮추고, 테스트 환경을 더욱 견고하게 만들 수 있습니다.

Python에서 unittest 모듈을 사용하여 단위 테스트를 작성할 수 있습니다. unittest 모듈은 테스트 케이스를 작성하여 코드의 동작을 확인하는 데 유용한 도구입니다. 이제 unittest 모듈을 사용하여 외부 서비스를 mock으로 대체하는 방법을 알아보겠습니다.

예시

아래는 외부 서비스와 상호작용하는 클래스를 가정한 예시 코드입니다.

import requests

class ExternalServiceClient:
    def __init__(self):
        self.service_url = 'https://api.external-service.com'

    def get_data(self):
        response = requests.get(self.service_url + '/data')
        return response.json()

위 코드는 ExternalServiceClient라는 외부 서비스와 통신하는 클래스입니다. 이 클래스의 get_data 메서드는 외부 서비스로부터 데이터를 가져오는 역할을 합니다.

이제 위 코드를 단위 테스트하기 위해 unittest 모듈을 사용하면서 외부 서비스를 mock으로 대체하는 방법을 알아보겠습니다.

import unittest
from unittest import mock
from my_module import ExternalServiceClient

class TestExternalServiceClient(unittest.TestCase):
    def test_get_data(self):
        # Mock으로 대체할 응답 데이터
        mock_response = {'key': 'value'}

        # 외부 서비스에 대한 모의 응답 생성
        with mock.patch('requests.get') as mock_get:
            mock_get.return_value.json.return_value = mock_response

            # 테스트할 클래스의 인스턴스 생성
            client = ExternalServiceClient()

            # get_data 메서드 호출
            data = client.get_data()

            # 모의 응답과 반환된 데이터 비교
            self.assertEqual(data, mock_response)

위 코드에서 unittest.TestCase를 상속받은 테스트 케이스 클래스인 TestExternalServiceClient를 정의하고, test_get_data라는 테스트 메서드를 작성하였습니다.

해당 테스트 메서드 안에서는 requests.get 함수를 모의(mock) 객체로 대체하고, 모의 응답을 설정합니다. 그리고 ExternalServiceClient 인스턴스를 생성하여 get_data 메서드를 호출합니다. 이렇게하면 실제 외부 서비스에 연결하지 않고도 테스트를 수행할 수 있습니다.

마지막으로, 모의 응답과 get_data 메서드가 반환한 데이터를 비교하는 assert 문을 추가합니다. 이를 통해 테스트의 성공 여부를 확인할 수 있습니다.

결론

위의 예시를 통해 Python의 unittest 모듈을 사용하여 외부 서비스를 mock으로 대체하는 방법을 알아보았습니다. 이를 통해 소프트웨어의 품질을 향상시키고 테스트의 견고성을 확보할 수 있습니다. 하지만 외부 서비스와의 상호작용이 많다면 mocking을 계속 사용하는 것보다는 실제 외부 서비스와 통합된 테스트도 진행하는 것이 좋습니다.