PYTHON · 테스트
mock/patch
unittest.mock으로 외부 의존성을 대체하여 단위 테스트를 격리합니다.
테스트중급mockpatch테스트격리
핵심 설명
unittest.mock으로 외부 의존성을 대체하여 단위 테스트를 격리합니다.
Python code
from unittest.mock import Mock, patch, MagicMock
# 기본 Mock
mock_db = Mock()
mock_db.query.return_value = [{"id": 1, "name": "Alice"}]
result = mock_db.query("SELECT * FROM users")
print(f"Mock 결과: {result}")
mock_db.query.assert_called_once_with("SELECT * FROM users")
# side_effect: 동적 반환값
mock_api = Mock()
mock_api.fetch.side_effect = [
{"status": 200}, # 첫 번째 호출
{"status": 200}, # 두 번째 호출
ConnectionError("실패"), # 세 번째 호출
]
print(mock_api.fetch())
print(mock_api.fetch())
try:
mock_api.fetch()
except ConnectionError as e:
print(f"예외: {e}")
# patch 데코레이터 패턴
def get_current_time():
from datetime import datetime
return datetime.now().isoformat()
# 테스트에서 시간 고정
with patch("datetime.datetime") as mock_dt:
from datetime import datetime
mock_dt.now.return_value = datetime(2024, 1, 1, 12, 0)
# get_current_time() 이 항상 같은 시간 반환
# spec으로 인터페이스 강제
class UserService:
def get_user(self, user_id: int) -> dict: ...
def create_user(self, name: str) -> dict: ...
mock_service = Mock(spec=UserService)
mock_service.get_user.return_value = {"name": "Alice"}
print(mock_service.get_user(1))
# mock_service.non_existent() # AttributeError (spec 위반)학습 팁
spec=True를 사용하면 Mock이 실제 객체의 인터페이스를 따르게 하여 오타로 인한 테스트 통과를 방지합니다.
주의할 점
너무 많은 것을 Mock하면 테스트가 구현에 결합됩니다. 외부 의존성(DB, API, 파일)만 Mock하세요.
자주 묻는 질문
mock/patch란 무엇인가요?
unittest.mock 으로 외부 의존성을 대체하여 단위 테스트를 격리합니다.
mock/patch 학습 시 주의할 점은 무엇인가요?
너무 많은 것을 Mock하면 테스트가 구현에 결합됩니다. 외부 의존성(DB, API, 파일)만 Mock하세요.