테스트 대역 용어

2025. 2. 8. 16:26·개발
반응형
  • 테스트 코드를 작성하면서 InMemoryRepository, FakeRepository, RepositoryStub 를 별다른 기준 없이 네이밍을 작성했다.
  • 다른 개발자들과 의사소통을 위해서는 일반적으로 사용하는 네이밍 규칙을 따를 필요가 있다고 생각해 테스트 대역에 사용하는 용어들에 대해 정리

Test Double

  • 우리말로 번역하면 테스트 대역이다. 여기서 대역은 대신 다른 역할을 하는걸 말한다.(잘 모를땐 주파수 대역을 떠올렸었다…)
  • 테스트에서 실제 객체를 대신하는 가짜 객체
  • 데이터베이스, 외부 API, 파일 시스템 등과 연결되어 있을 경우 테스트를 작성하기 어려워진다. 이 때 외부 의존성을 대신하는 객체를 만들어 테스트를 작성할 수 있다.
    • 외부 의존성 없이 순수하게 테스트
  • Test Double을 사용하면:
    • 외부 의존성 없이 순수하게 테스트 대상 클래스의 로직만 검증할 수 있다.
    • 예측 가능한 결과를 반환하도록 설정해 다양한 시나리오에 대한 테스트가 가능하다.
    • 테스트 실행 속도를 크게 향상시킨다. - 직접 DB를 실행하는 것 보다 대역을5 사용한다.

종류

Test Double은 목적과 동작 방식에 따라 5가지로 구분할 수 있다.

Dummy

  • 의존성은 있지만 해당 테스트에서는 사용하지 않는 객체가 필요할 때 사용한다.
@Test
void test01() {
    // 실제로 사용되지 않는다.
    NotificationService dummyNotification = null;

    UserService userService = new UserService(userRepository, dummyNotification);

    // 이 테스트에서는 알림 기능을 사용하지 않으므로 null이어도 문제없다.
    User user = userService.createUser("user01@example.com");

    assertThat(user.getEmail()).isEqualTo("user01@example.com");
}

Fake

  • 실제 구현체보다 단순하지만 동일하게 동작하는 구현을 가진 객체
  • 실제 외부 시스템 없이 동작하는 구현체가 필요할 때 사용(메모리 DB, 파일 시스템 등)
// Fake Repository - 메모리 기반으로 동작
public class FakeUserRepository implements UserRepository {
    private final Map<Long, User> users = new ConcurrentHashMap<>();
    private final AtomicLong idGenerator = new AtomicLong(1);

    @Override
    public User save(User user) {
        user.setId(idGenerator.incrementAndGet());
        users.put(user.getId(), user);
        return user;
    }

    @Override
    public Optional<User> findById(Long id) {
        return Optional.ofNullable(users.get(id));
    }
}

@Test
void test02() {
    UserRepository fakeRepository = new FakeUserRepository();
    UserService userService = new UserService(fakeRepository);

    User savedUser = userService.createUser("user02@example.com");
    User foundUser = userService.findById(savedUser.getId());

    assertThat(foundUser.getEmail()).isEqualTo("user02@example.com");
}

Stub

  • 테스트에 필요한 호출에 대해 미리 정해둔 응답만 반환하는 객체
  • 특정 입력에 대한 예측 가능한 출력이 필요할 때 사용
@Test
void test03() {
    // 미리 정해진 응답만 반환
    ExternalApiClient stubApiClient = Mockito.mock(ExternalApiClient.class);
    given(stubApiClient.getUserInfo(any())).willReturn(
        new UserInfo("user01", "user01@example.com")
    );

    UserService userService = new UserService(stubApiClient);
    UserInfo result = userService.fetchUserInfo("12345");

    assertThat(result.getName()).isEqualTo("user01");
    assertThat(result.getEmail()).isEqualTo("user01@example.com");
}

Spy

  • Stub의 기능에 더해 메서드 호출 정보를 기록하는 객체
  • 메서드가 올바르게 호출되었는지 확인하면서 실제 동작도 필요할 경우 사용
@Test
void test04() {
    // Spy - 호출 내역을 기록
    EmailService spyEmailService = Mockito.spy(new EmailService());

    UserService userService = new UserService(userRepository, spyEmailService);
    userService.registerUser("john@example.com");

    // 이메일이 정확히 한 번 호출되었는지 확인
    verify(spyEmailService, times(1)).sendWelcomeEmail("john@example.com");
}

Mock

  • 호출 횟수, 파라미터, 호출 순서 등을 미리 설정하고 검증하는 객체
  • 메서드 호출 여부, 횟수, 순서 등의 행위를 검증해야할 경우 사용
@Test
void test05() {
    PaymentService mockPaymentService = mock(PaymentService.class);
    OrderRepository mockOrderRepository = mock(OrderRepository.class);

    // 실패 시나리오 설정
    given(mockPaymentService.processPayment(any())).willThrow(new PaymentException());

    OrderService orderService = new OrderService(mockOrderRepository, mockPaymentService);

    assertThrows(PaymentException.class, () -> {
        orderService.createOrder("item123", 100);
    });

    // 결제 실패 시 주문이 저장되지 않았는지 검증
    verify(mockOrderRepository, never()).save(any(Order.class));
    verify(mockPaymentService, times(1)).processPayment(any());
}

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'개발' 카테고리의 다른 글
  • 동시성 이슈 해결하기
  • 로컬 개발환경에서 https 사용
덴마크초코우유
덴마크초코우유
IT, 알고리즘, 프로그래밍 언어, 자료구조 등 정리
    반응형
  • 덴마크초코우유
    이것저것끄적
    덴마크초코우유
  • 전체
    오늘
    어제
    • 분류 전체보기 (122)
      • Spring Framework (9)
        • Spring (5)
        • JPA (2)
        • Spring Security (0)
      • Language (51)
        • Java (11)
        • Python (10)
        • JavaScript (5)
        • NUXT (2)
        • C C++ (15)
        • PHP (8)
      • DB (16)
        • MySQL (10)
        • Reids (3)
        • Memcached (2)
      • 개발 (3)
      • 프로젝트 (2)
      • Book (2)
      • PS (15)
        • 기타 (2)
        • 백준 (2)
        • 프로그래머스 (10)
      • 딥러닝 (8)
        • CUDA (0)
        • Pytorch (0)
        • 모델 (0)
        • 컴퓨터 비전 (4)
        • OpenCV (1)
      • 기타 (16)
        • 디자인패턴 (2)
        • UnrealEngine (8)
        • ubuntu (1)
        • node.js (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    게임
    pytorch
    자바
    블루프린트
    게임 개발
    웹
    C++
    클래스
    PS
    알고리즘
    딥러닝
    파이썬
    Unreal Engine
    NUXT
    select
    MySQL
    FPS
    언리얼엔진4
    C
    Python
    JS
    php
    프로그래머스
    Unreal
    CPP
    mscoco
    map
    redis
    memcached
    JavaScript
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
덴마크초코우유
테스트 대역 용어
상단으로

티스토리툴바