[테스트 주도 개발] 15장_서로 다른 통화 더하기

이제 드디어, “5달러 + 10프랑” 테스트할 준비가 모두 되었다.
우리가 원하는 코드는,

1
2
3
4
5
6
7
8
9
10
11
@Test
void testMixedAddition() {
Expression fiveBucks = Money.dollar(5);
Expression tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Money result = bank.reduce(
fiveBucks.plus(tenFrancs), "USD"
);
assertEquals(Money.dollar(10), result);
}

컴파일 에러가 많다. 천천히 해결하자.

1
2
3
4
5
6
7
8
9
10
11
@Test
void testMixedAddition() {
Money fiveBucks = Money.dollar(5);
Money tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Money result = bank.reduce(
fiveBucks.plus(tenFrancs), "USD"
);
assertEquals(Money.dollar(10), result);
}

실패한다. 10 USD 대신, 15 USD 가 나왔다. Sum.reduce() 가 인자를 축약하지 않은 것으로 보인다. 다음과 같이 두 인자를 모두 축약하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Sum implements Expression {
Money augend;
Money addend;

Sum(Money augend, Money addend) {
this.augend = augend;
this.addend = addend;
}

public Money reduce(Bank bank, String to) {
int amount = augend.reduce(bank, to).amount +
addend.reduce(bank, to).amount;
return new Money(amount, to);
}
}

그리고, Expression 이어야하는 Money 들을 조금씩 없앨 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Sum implements Expression {
Expression augend;
Expression addend;

Sum(Expression augend, Expression addend) {
this.augend = augend;
this.addend = addend;
}

public Money reduce(Bank bank, String to) {
int amount = augend.reduce(bank, to).amount +
addend.reduce(bank, to).amount;
return new Money(amount, to);
}
}

Money 의 plus() 인자도 바꾸자.

1
2
3
Expression plus(Expression addend){
return new Sum(this, addend);
}

테스트 케이스에 나오는 plus() 의 인자를 다음 처럼 바꾸자.

1
2
3
4
5
6
7
8
9
10
11
@Test
void testMixedAddition() {
Money fiveBucks = Money.dollar(5);
Expression tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Money result = bank.reduce(
fiveBucks.plus(tenFrancs), "USD"
);
assertEquals(Money.dollar(10), result);
}

fiveBucks 를 Expression 으로 바꾸고 나면, 몇 군데 수정해야한다. 컴파일러가 할 일 목록을 제공하기 때문에 우린 계속 집중할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
@Test
void testMixedAddition() {
Expression fiveBucks = Money.dollar(5);
Expression tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Money result = bank.reduce(
fiveBucks.plus(tenFrancs), "USD"
);
assertEquals(Money.dollar(10), result);
}

컴파일러가 Expression 에 plus() 가 정의되어 있지 않다고 한다. 정의하자.

1
2
3
4
5
interface Expression {
Money reduce(Bank bank, String to);

Expression plus(Expression addend);
}

이제 Money 와 Sum 에도 추가하자. Money 에서는 기존에도 있었다. public 으로 해주자.

1
2
3
public Expression plus(Expression addend){
return new Sum(this, addend);
}

Sum 에는 스텁 구현으로 하자.

1
2
3
4
@Override
public Expression plus(Expression addend) {
return null;
}

테스트 주도 개발 <켄트 벡>

Comments