파이썬에서 다른 서비스를 import 해서 쓰는 경우와 init 에 정의해서 쓰는 경우가 있다. 이 두가지 경우에 다른 서비스를 mocking 하는 경우 차이가 생긴다.
1. __init__에서 서비스를 정의하는 경우 (Dependency Injection)
- 서비스 객체를 클래스 외부에서 생성하고, 인스턴스 생성 시 __init__을 통해 주입한다.
- 테스트에서 의존성을 쉽게 교체할 수 있다.
- Mocking이 간단하며, 클래스 내에서 서비스가 직접 호출되더라도 Mock을 주입할 수 있다.
# app/services.py
class DependencyService:
def get_data(self):
return {"key": "real_value"}
class MyService:
def __init__(self, dependency_service: DependencyService):
self.dependency_service = dependency_service
def process(self):
data = self.dependency_service.get_data()
return {"processed": data["key"]}
# 테스트 코드
from unittest.mock import MagicMock
from app.services import MyService, DependencyService
def test_my_service_with_mock():
# Mock DependencyService 생성
mock_dependency_service = MagicMock(spec=DependencyService)
mock_dependency_service.get_data.return_value = {"key": "mocked_value"}
# MyService에 Mock 주입
service = MyService(dependency_service=mock_dependency_service)
result = service.process()
# 검증
assert result == {"processed": "mocked_value"}
mock_dependency_service.get_data.assert_called_once()
- 장점
테스트 가능성 증가: 의존성을 외부에서 주입하므로, 테스트 시 Mock 객체를 쉽게 교체할 수 있음.
유연한 의존성 관리: 다른 의존성(예: 테스트 환경, 프로덕션 환경)을 쉽게 교체 가능.
- 단점
의존성을 외부에서 관리해야 하므로 DI(Dependency Injection)를 지원하지 않는 프로젝트에서는 초기 설정이 다소 번거로울 수 있음.
2. 클래스 내부에서 import 하는 경우
- 클래스 내부에서 직접 import하여 의존성을 사용한다.
- Mocking 시 패치 대상 경로가 클래스 코드의 import 경로와 일치해야 한다.
- Mocking이 번거롭거나, 테스트마다 Mock을 설정해야 할 수 있다.
# app/services.py
from app.dependencies import DependencyService
class MyService:
def process(self):
dependency_service = DependencyService()
data = dependency_service.get_data()
return {"processed": data["key"]}
# 테스트 코드
from unittest.mock import patch
from app.services import MyService
@patch("app.services.DependencyService")
def test_my_service_with_mock(mock_dependency_service):
# Mock 메서드 설정
mock_dependency_service_instance = mock_dependency_service.return_value
mock_dependency_service_instance.get_data.return_value = {"key": "mocked_value"}
# MyService 테스트
service = MyService()
result = service.process()
# 검증
assert result == {"processed": "mocked_value"}
mock_dependency_service_instance.get_data.assert_called_once()
- 장점
간단한 의존성 사용: 의존성을 별도로 관리하지 않고 클래스 내에서 바로 사용 가능.
코드 단순화: DI 설정이 필요하지 않음.
- 단점
Mocking이 번거로움:
패치 대상 경로(app.services.DependencyService)를 정확히 지정해야 함.
의존성이 많아질수록 관리가 어려움.
테스트 간 결합 가능성:
같은 테스트 환경에서 Mock 설정이 공유될 가능성이 있음.
'Development > Python' 카테고리의 다른 글
Python 웹 스크래핑 하기2 (1) | 2024.10.17 |
---|---|
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (0) | 2024.08.27 |
Python 웹 스크래핑 하기 (0) | 2024.08.20 |
[Python] Blob Storage 에 Connection String 으로 연결하기 (0) | 2024.08.01 |
python 으로 Azure blob storage 연결 (0) | 2024.07.12 |