Contents
테스트 코드 작성 순서 예제(1)
   Sep 19, 2022     5 min read

테스트 작성 순서 연습(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부에서 정리해서 또 올리겠다.