본문 바로가기
Development/Python

파이썬 Test Case 작성시 init 과 import....

by 폴피드 2025. 1. 9.
728x90
반응형

파이썬에서 다른 서비스를 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 설정이 공유될 가능성이 있음.

 

728x90
반응형