테스트 코드 작성 순서 예제(1)
테스트 작성 순서 연습(1)
매달 비용을 지불해야 사용할 수 있는 유료 서비스 예제로 테스트 작성 순서 연습을 해보자.
매달 비용 지불하는 서비스는 엄청 많다. 앞으로 더 생기기도 하는 추세이기도하다.
⚠️규칙
1. 서비스를 사용하려면 매달 1만 원을 선불로 납부한다.납부일 기준으로 한 달 뒤가 서비스 만료일이 된다.
2. 2개월 이상 요금을 납부할 수 있다.
3. 10만 원을 납부하면 서비스를 1년 제공한다.
순서는 쉬운 것부터 처리하는 것이 심적인 부담에 좋을 거같아서 1 번부터 3번 차례대로 하겠다.
테스트 목록 정리
- 1만 원 지불 시 구독 서비스 한달 뒤 만료일
- 달의 마지막 날에 지불하면 다음달 마지막 날이 서비스 종료(만료일)
- 2만 원 지불하면 2개월 뒤가 서비스 종료일(만료일)
- 3만 원 지불하면 3개월 뒤 서비스 종료일
- 10만원 지불하면 1년 뒤가 서비스 종료일
- 10만원 이상 지불할 경우 (13만원)
- 2월 29일과 같은 윤달일 경우 마지막 날에 10만 원을 지불할 경우
클래스 작명하는 것 (※매우 중요)
클래스 작명하는것도 정말 중요하다. 그렇기 때문에 만료일(expiry date)
+
계산기 (calculator)
+
Test
로 설정하여 ExpirydateCalculatorTest
public class ExpiryDateCalculatorTest{
}
1만원 지불할 경우
➡️1만 원 지불할 경우 Test 코드
public class ExpiryDateCalculatorTest{
@Test
void 만원_납부하면_한달_뒤_만료일(){
LocalDate billingDate = LocalDate.of(2022,3,1); //지불 날짜
int payAmount = 10_000; // 지불 금액
ExpiryDateCalculator cal = new ExpiryDateCalculator();
LocalDate expiryDate = cal.calculatorExpiryDate(billingDate, payAmount);
Assertions.assertEquals(LocalDate.of(2022,4,1), expiryDate);
}
}
➡️1만 원 지불할 경우 구현 코드
- 상수를 리턴해서 구현
import java.time.LocalDate;
public class ExpiryDateCalculator {
public LocalDate calculatorExpiryDate(LocalDate billingDate, int payAmount){
return LocalDate.of(2022, 4, 1);
}
}
➡️ 테스트 통과
테스트를 통과했지만 비슷한 예시를 더 추가하면서 구현을 일반화 해보자.
➡️ 테스트 코드 추가
public class ExpiryDateCalculatorTest{
@Test
void 만원_납부하면_한달_뒤_만료일(){
LocalDate billingDate = LocalDate.of(2022,3,1);
int payAmount = 10_000;
ExpiryDateCalculator cal = new ExpiryDateCalculator();
LocalDate expiryDate = cal.calculatorExpiryDate(billingDate, payAmount);
assertEquals(LocalDate.of(2022,4,1), expiryDate);
//--------------- 예시 추가 ---------------
LocalDate billingDate2 = LocalDate.of(2022, 5, 5);
int payAmount2 = 10_000;
ExpiryDateCalculator cal2 = new ExpiryDateCalculator();
LocalDate expiryDate2 = cal2.calculatorExpiryDate(billingDate2, payAmount2);
assertEquals(LocalDate.of(2022,6,5), expiryDate2);
}
}
➡️ 구현
plusMonths(1)
를 사용- 상수 대신에 구현을 일반화해서 구현
public class ExpiryDateCalculator {
public LocalDate calculatorExpiryDate(LocalDate billingDate, int payAmount){
return billingDate.plusMonths(1);
}
}
테스트를 통과했으면 바로 코드 정리를 바로바로 하자.
- 아래와 같이 구현을 한 코드를 일반화한다.
LocalDate billingDate = 지불 날짜;
int paymentAmount = 지불 금액;
ExpiryDateCalculator cal = new ExpiryDateCalculator();
LocalDate expiryDate = cal.calculateExpiryDate(billingDate, paymentAmount);
assertEquals(기댓값, expiryDate);
Tip. 보통 중복을 제거하는 것이 좋지만, 테스트 코드의 중복 제거는 신중해야한다. 각 테스트 메서드는 스스로 무엇을 테스트하는지 명확하게 설명할 수 있어야 하기 때문이다.
➡️테스트 코드를 정리한 결과
public class ExpiryDateCalculatorTest{
@Test
void 만원_납부하면_한달_뒤_만료일(){
assertExpiryDate(
LocalDate.of(2022,3,1), 10_000,
LocalDate.of(2022,4,1));
assertExpiryDate(
LocalDate.of(2022,3,1), 10_000,
LocalDate.of(2022,4,1));
}
private void aseertExpiryDate(LocalDate billingDate, int payAmount, LocalDate expectedExpiryDate){
ExpiryDateCalculator cal = new ExpiryDateCalculator();
LocalDate realExpiryDate = cal.calculateExpiryDate(billingDate, payAmount);
assertEquals(expectedExpiryDate, realExpiryDate);
}
}
예외 상황 처리
앞에 구현한 것을 예외상황을 찾아보자.
지금까지 순서
테스트 → 구현 → 통과 → 예를 추가 → 구현을 일반화 → 예외 상황 처리
예외 상황을 생각해보자.
- 지불 날짜 2022년 01월 31일이고 지불 금액 1만원, 만료일은 2022년 02월 28일이다.
- 지불 날짜 2022년 05월 31일이고 지불 금액 1만원, 만료일은 2022년 06월 30일이다.
- 지불 날짜 2022년 01월 31일이고 지불 금액 1만원, 만료일은 2022년 02월 29일이다.
public class ExpiryDateCalculatorTest{
@Test
void 만원_납부하면_한달_뒤가_만료일(){
assertExpiryDate(LocalDate.of(2022,1,31),10_000,
Localdate.of(2022,2,28));
}
private void aseertExpiryDate(LocalDate billingDate, int payAmount, LocalDate expectedExpiryDate){
ExpiryDateCalculator cal = new ExpiryDateCalculator();
LocalDate realExpiryDate = cal.calculateExpiryDate(billingDate, payAmount);
assertEquals(expectedExpiryDate, realExpiryDate);
}
}
➡️두 개의 예시를 한번에 추가하기
@Test
void 납부한일과_한달_뒤_일자가_같지_않음(){
assertExpiryDate{
LocalDate.of(2022,1,31), 10_000,
LocalDate.of(2022,2,28));
assertExpiryDate{
LocalDate.of(2022,5,31), 10_000,
LocalDate.of(2022,6,30));
assertExpiryDate{
LocalDate.of(2022,1,31), 10_000,
LocalDate.of(2022,2,29));
}
}
- 모두 통과 → LocalDate에서 plusMonth()메서드가 알아서 한 달 추가 처리를 해준다.
오늘은 여기 까지만 하고 다음 2부에서 정리해서 또 올리겠다.