들어가기전에 명심할 단계는
이다.
자 그럼 해당 과정을 기억하고 들어가보자!
다음과 같은 보고서가 있다고 하자.
종목 | 주 | 가격 | 합계 |
---|---|---|---|
IBM | 1000 | 25USD | 25000USD |
Novartis | 400 | 150CHF | 60000CHF |
합계 | 65000USD |
다중 통화를 지원하는 보고서를 만들려면 통화 단위를 추가해야 한다.
기준 | 변환 | 환율 |
---|---|---|
CHF | USD | 1.5 |
통화가 다른 두 금액을 더해서 주어진 환율에 맞게 변한 금액을 결과로 얻을 수 있어야 한다.
어떤 금액(주가)을 어떤 수 (주식의 수)에 곱한 금액을 결과로 얻을 수 있어야 한다.
우선 어떤 테스트가 필요할까?
@Test
public void testMultiplication(){
Dollar five = new Dollar(5);
five.times(2);
Assertions.assertEquals(10, five.amount);
}
실패하는 테스트가 주어진 상태이고 최대한 빨리 초록 막대를 보고 싶을 뿐이다.
$5 + 10 CHF = $10(환율이 2:1일 경우)
$5 X 2 = $10
amount를 private으로 만들기
Dollar 부작용(side effect)?
Money 반올림
일단 테스트조차 진행이 안될텐데 아래의 목록이 그 이유이다.
이 목록에 따라 일단 테스트 실행을 위해 클래스 정의를 시작하자
public class Dollar {
int amount;
public Dollar(int amount) {
}
public void times(int multiplier) {
}
}
테스트를 실행해서 테스트가 실패하는 모습을 볼 수 있게 됐다.
슬프다... 빨간 막대다.
우리 문제는 다중 통화 구현
에서 이 테스트를 통과시킨 후 나머지 테스트들도 통과시키기
로 변형된 것이다. 훨씬 간단하다. 범위도 훨씬 적어서 걱정이 줄었다.
일단 적절한 방법인지는 모르겠고 일단 통과부터 시켜보자
...
이렇게 하면 되겠지만 뭔가 존나 찝찝하다
public class Dollar {
int amount = 10;
.
.
.
}
이렇게 해도 당장에 10이라는 걸 2랑 5로 나누어 놨기 때문에 다른 테스트에서 통과는 되겠지만 아직 찝찝하다
public class Dollar {
int amount = 2 * 5;
.
.
.
}
그럼 times()메서드 안으로 해당 내용을 옮겨보면 어떨까?
당장에 times를 사용해서 테스트 마지막 값을 정하니 맞겠지만 역시나 찝찝이다.
public class Dollar {
int amount;
public void times(int multiplier) {
this.amount = 5 * 2;
}
}
5를 어디서 얻을 수 있을까? 이건 생성자에서 넘어오는 값이니 이걸 다음과 같이 amount변수에 저장하면
public Dollar(int amount) {
this.amount = amount;
}
앞전에본 5 * 2에서 5라는 상수를 amount로 대체한다면 그리고 2라는 값을 인자로 대체해준다면 뭔가 그럴듯하게 드디어 첫번째 테스트를 완수 시킬수 있다.
public void times(int multiplier) {
this.amount *= multiplier;
}
현재 Dollar class이다.
public class Dollar {
int amount;
public Dollar(int amount) {
this.amount = amount;
}
public void times(int multiplier) {
this.amount *= multiplier;
}
}
$5 + 10 CHF = $10(환율이 2:1일 경우)
$5 X 2 = $10
amount를 private으로 만들기
Dollar 부작용(side effect)?
Money 반올림
되돌이켜보면 우리는 다음 작업들을 했다.