단위테스트

qkdk·2024년 1월 30일
0

TDD

목록 보기
2/12

단위 테스트

  • 작은 코드 단위를 독립적으로 검증하는 테스트
  • 검증 속도가 빠르고 안정적이다.

테스트 케이스 세분화 하기

  • 해피 케이스
  • 예외 케이스

→ 경계값 테스트

범위(이상, 이하, 초과, 미만), 구간, 날짜 등

테스트하기 어려운 영역 분리하기

문제상황

  • 현재 시간에 의존하여 테스트가 실패하는 경우, 성공하는 경우 발생

ProductionCode

private static final LocalTime SHOP_OPEN_TIME = LocalTime.of(10, 0);
private static final LocalTime SHOP_CLOSE_TIME = LocalTime.of(22, 0);

public Order createOrder() {
    LocalDateTime currentDateTime = LocalDateTime.now();
    LocalTime currentTime = currentDateTime.toLocalTime();
    if (currentTime.isBefore(SHOP_OPEN_TIME) || currentTime.isAfter(SHOP_CLOSE_TIME)) {
        throw new IllegalArgumentException("주문 시간이 아닙니다. 관리자에 문의하세요.");
    }
    return new Order(currentDateTime, beverages);
}

TestCode

@Test
void createOrderTest(){
    CafeKiosk cafeKiosk = new CafeKiosk();
    Americano americano = new Americano();

    cafeKiosk.add(americano);

    Order order = cafeKiosk.createOrder();

    assertThat(order.getBeverages()).hasSize(1);
    assertThat(order.getBeverages().get(0).getName()).isEqualTo("아메리카노");
}

해결방법

  • 시간을 외부에서 입력받는다.

ProductionCode

private static final LocalTime SHOP_OPEN_TIME = LocalTime.of(10, 0);
private static final LocalTime SHOP_CLOSE_TIME = LocalTime.of(22, 0);

public Order createOrder(LocalDateTime currentDateTime) {
    LocalTime currentTime = currentDateTime.toLocalTime();

    if (currentTime.isBefore(SHOP_OPEN_TIME) || currentTime.isAfter(SHOP_CLOSE_TIME)) {
        throw new IllegalArgumentException("주문 시간이 아닙니다. 관리자에 문의하세요.");
    }

    return new Order(currentDateTime, beverages);
}

TestCode

@Test
void createOrderWithCurrentTime() {
    CafeKiosk cafeKiosk = new CafeKiosk();
    Americano americano = new Americano();

    cafeKiosk.add(americano);

    Order order = cafeKiosk.createOrder(LocalDateTime.of(2023, 1, 17, 10, 0));

    assertThat(order.getBeverages()).hasSize(1);
    assertThat(order.getBeverages().get(0).getName()).isEqualTo("아메리카노");
}

@Test
void createOrderWithOutsideOpenTime() {
    CafeKiosk cafeKiosk = new CafeKiosk();
    Americano americano = new Americano();

    cafeKiosk.add(americano);

    assertThatThrownBy(() -> cafeKiosk.createOrder(LocalDateTime.of(2023, 1, 17, 9, 0)))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("주문 시간이 아닙니다. 관리자에 문의하세요.");
}

테스트하기 어려운 영역

  1. 관측할 때마다 다른 값에 의존하는 코드
    • 현재 날짜/시간, 랜덤 값, 전역 변수/함수, 사용자 입력
  2. 외부 세계에 영향을 주는 코드
    • 표준 출력, 메시지 발송, 데이터 베이스에 기록하기 등

→ 순수함수를 만들자!

  • 같은 입력에는 항상 같은 결과
  • 외부 세상과 단절된 형태
  • 테스트하기 쉬운 코드
profile
qkdk

0개의 댓글