[pytest] Mocking은 언제, 얼마나 해야 할까? - Pytest Mocking 전략

최승언·2024년 11월 29일
0

pytest

목록 보기
2/2
post-thumbnail

테스트 코드를 작성하면서 자주 고민하는 부분 중 하나는 "Mocking을 얼마나, 어떻게 해야 할까?"입니다. Mocking은 강력한 도구이지만, 과도하게 사용하면 원본 코드와 테스트 코드의 결합도가 높아지고 유지보수성이 떨어질 수 있습니다. 이 글에서는 Pytest를 사용하여 Mocking을 효과적으로 사용하는 방법과 그 한계를 다룹니다.


1. Mocking은 왜 필요한가?

Mocking은 주로 다음과 같은 이유로 사용됩니다:

  • 외부 의존성 제거: 외부 API, 데이터베이스, 파일 시스템 등 실제 호출할 필요가 없는 부분을 대체합니다.

  • 테스트 속도 향상: 느리거나 무거운 의존성을 대신합니다.

  • 상황 시뮬레이션: 특정 조건(예: 네트워크 오류)을 인위적으로 재현할 수 있습니다.

2. Mocking의 문제점

Mocking을 너무 많이 사용하거나 모든 의존성을 Mock으로 대체해야 한다는 강박이 있다면, 다음과 같은 문제가 발생할 수 있습니다:

  • 원본 코드와 테스트 코드 간 결합: 원본 코드가 변경되면 테스트 코드도 수정해야 할 가능성이 높아집니다.

  • 테스트 신뢰도 저하: Mock이 실제 동작을 정확히 모사하지 못하면, 테스트 결과가 신뢰성을 잃을 수 있습니다.

  • 중복 작업 증가: 원본 코드의 논리를 테스트 코드에서 재현해야 할 수도 있습니다.

3. 실용적인 접근법

Mocking으로 인한 문제를 최소화하면서도 테스트를 효과적으로 작성하기 위한 전략은 다음과 같습니다:

(1) Mocking을 최소화하기

  • Mocking은 꼭 필요한 외부 의존성(API, DB 등)이나 느리고 복잡한 의존성에만 적용합니다.

  • 내부 메서드나 클래스는 Mocking 없이 실제 구현을 테스트하는 것이 좋습니다.

(2) 테스트 대상의 범위 결정하기

  • 유닛 테스트: 작은 단위의 코드만 테스트하므로, 의존성을 Mock 처리할 때도 있지만 공개 인터페이스를 기준으로 테스트합니다. 내부 구현은 검증 대상이 아닙니다.

  • 통합 테스트: 여러 구성 요소를 통합한 상태에서 테스트하며, Mocking을 줄이고 실제 환경에 가까운 의존성을 사용합니다.

(3) 인터페이스 중심 테스트 작성하기

  • 함수나 클래스의 동작(입력-출력)에 초점을 맞추고, 내부 구현 세부 사항은 테스트에서 다루지 않습니다.

  • 내부 메서드 호출 여부를 검증하기보다는, 결과값이나 상태 변화를 검증합니다.

(4) Mock 유지보수 줄이기

  • Mock 객체는 코드 변경에 강건하도록 설계해야 합니다. Mock의 반환값을 호출 횟수나 내부 구현에 의존하기보다는, 반환값 자체에 초점을 맞춥니다.

  • Python의 autospec을 활용하여 원본 인터페이스를 기반으로 Mock을 생성하면, 예상치 못한 변경을 막을 수 있습니다:

from unittest.mock import create_autospec

### 예시
class Service:
    def get_data(self):
        pass

mock_service = create_autospec(Service)
mock_service.get_data.return_value = "mocked data"

(5) 테스트와 원본 코드의 적절한 분리

테스트 코드는 원본 코드의 동작을 검증하며, 구현 세부 사항에 대한 의존을 최소화해야 합니다.

Mocking이 과도하게 필요하다면, 원본 코드의 의존성이 지나치게 복잡하거나 응집도가 낮을 수 있습니다.

4. 요약

Mock은 필요할 때만 사용하세요(외부 의존성, 테스트 환경 시뮬레이션 등).

내부 메서드나 클래스는 가능한 한 실제 구현을 테스트하고, 동작(결과)을 검증하세요.

테스트 코드와 원본 코드 간 결합도를 낮춰 유지보수성을 높이세요.

Mocking이 필요할 경우, 인터페이스 중심으로 작성해 변경에 유연하게 대처하세요.

결론

Mocking은 잘 사용하면 강력한 도구지만, 과도하게 사용하면 테스트 코드와 원본 코드의 결합도를 높이고 유지보수를 어렵게 만듭니다. Mocking의 필요성을 신중히 판단하고, 원본 코드의 동작을 중심으로 테스트 코드를 작성하여 유지보수성과 신뢰성을 확보하세요.

profile
작업하다가 막힌부분을 기록하는 곳.

0개의 댓글