[Practical Testing: 실용적인 테스트 가이드]
섹션 3. 단위테스트
: 작은 코드 단위를 독립적으로 검증하는 테스트
작은 코드 : 클레스 or 매서드
: 단위 테스트를 위한 테스트 프레임워크
5는 버전이며 언어에 따라 이름이 변경됨 (XUnit)
: 테스트 코드 작성을 원할하게 돕는 테스트 라이브러리
assertEquals(a, b)
: Junit의 assert문 a와 b가 같은지
assertThat(a).isEquaslTo(b)
: AssertJ API사용 / 이게 보다 명시적. 메서드 체이닝 가능
경계값 테스트 - 범위(이상, 이하, 초과, 미만), 구간, 날짜 등
테스트 케이스를 세분화 한 다음에 경계값이 존재하는 경우에는 경계값에서 항상 테스트 할 수 있도록 고민하는 게 중요하다.
예외 테스트는 assertThatThrownBy()
사용
isInstanceOf()
에 발생할 오류 삽입
hasMessage()
에서 메시지 검증
assertThatThrownBy(() -> cafeKiosk.add(americano, 0)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("음료는 1잔 이상 주문하실 수 없습니다.");
테스트 가능한 코드가 있을 때 현재의 일시를 가지고 제약 조건을 걸게 되면 테스트가 어려운 코드가 들어오게 된다. 그렇게 되면 전체가 테스트 불가능한 상태가 된다. 그래서 테스트를 수행할 때마다 값이 달라져서 테스트의 성공여부를 예상할 수 없게 된다.
조치 방안으로 테스트 어려운 영역을 외부로 분리한다. LocalDateTime
을 외부에서 받도록 파라미터를 분리해서 실제 CafeKioskRunner
에서 수행할 때는 프로덕션 코드에 LocalDateTime.now()
를 넣어서 원하는 기능을 동작하도록 하고 테스트 코드에서는 우리가 원하는 코드를 넣어준다.
❓ 이렇게 테스트해도 되는가요?
❗ 우리가 검증하고자 하는 것은
LocalDateTime.now()
가 아니다. 테스트하고자 하는 영역은 어떤 시간이 주어졌을 때 이 시간 범위 안에 이 시간이 들어오는지 여부가 중요하다.
테스트 코드 상에서 원하는 값을 넣어줄 수 있도록 설계를 변경하는 것이 중요하다.
테스트 어려운 영역을 외부로 분리할수록 테스트 가능한 코드는 많아진다.
📑 출처