다중 통화를 지원하는 Money 객체

테스트 목록

테스트 필요한 해야할 목록을 작성한다.

  • $5 + 10CHF = $10(환율이 2:1 일 경우)

  • $5 * 2 = 10$

사용자 입장에서의 시나리오

테스트를 작성할 때는 오퍼레이션의 완벽한 인터페이스에 대해 상상해보는 것이 좋다.

즉, 오퍼레이션이 외부에서 어떤 식으로 보일 지에 대한 이야기를 테스트 코드로 적고 있는 것이다.

circle-info

오퍼레이션

객체가 수행할 수 있는 연산을 의미하며, 오퍼레이션에 대한 특정한 구현을 메서드라고 부른다.

다형성을 통해, 한 오퍼레이션은 여러 메서드를 가질 수 있다.

    @Test
    void testMultiplication() {
        Dollar five = new Dollar(5);
        five.times(2);
        assertEquals(10, five.amount);

    }

작은 단계로 시작

위 테스트는 예기치 못한 부작용을 고려하지 않았고, 금액 계산도 정수형으로 하였다.

하지만, 우선 이러한 문제 사항들은 목록에 추가하고, 작은 단계로 시작해보는 것이 중요하다.

  • $5 + 10CHF = $10(환율이 2:1 일 경우)

  • $5 * 2 = 10$

  • amount를 private으로 만들기

  • Dollar 부작용(side effect)?

  • Money 반올림?

우선 컴파일 되게 만들자!

아직은 컴파일 조차 되지 않는다. 따라서 에러를 보고 하나씩 고쳐나가 보자.

문제 상황을 적어보자.

  • Dollar 클래스가 없음

  • 생성자가 없음

  • times 메서드가 없음

  • amount 필드가 없음

하나씩 해결해보자. 우선 Dollar 클래스를 생성하여 첫 번째 에러를 제거한다.

하지만 생성자가 없다는 에러와 times() 메서드가 없다는 에러, amount 필드가 없다는 에러 또 다시 발생한다. 순차적으로 하나씩 에러를 제거해보자.

따라서, Dollar 클래스에 생성자를 추가하여 첫 번째 에러를 제거한다.

다음으로 times() 메서드를 위해서는 스텁 구현이 필요하며, 이를 통해 에러를 제거한다.

circle-info

스텁 구현

메서드의 서명부와 반환 값을 적으며, 이 메서드를 호출하는 코드가 컴파일이 될 수 있도록 껍데기가 만들어 주는 것을 의미한다.

마지막으로 amount 필드를 추가하여 에러를 제거한다.

결과적으로 테스트는 실패하지만 컴파일이 되는 것을 확인할 수 있다.

테스트 통과시켜 보자!

원하는 결과는 10 이지만, 실제 결과가 0 이 나온 것을 확인할 수 있다. 테스트에서는 실패했지만, 나아진 것은 '다중 통화 구현'에서 '이 테스트를 통과 시킨 후 나머지 테스트도 통과시키기'로 변형되었다는 것이다.

해당 빨간 막대를 해결하기 위한 최소 작업은 아래와 같다.

드디어 초록 막대를 볼 수 있게 되었다!

테스트 주기

하지만, 진정하고 테스트 주기에서의 현재 자신의 단계를 생각해보자. 테스트 주기는 아래와 같다.

circle-exclamation

중복 제거 위한 리팩토링

triangle-exclamation

이제 5번을 실행할 단계이다. 하지만 어디에 중복이 존재한단 말인가? 이번 경우에는 코드가 아닌 데이터의 중복이 있는 것을 확인할 수 있다. 코드에서의 amount 필드가 5 * 2 나누어 생각해보면, 테스트에서의 5, 2와 데이터가 중복되는 것을 확인할 수 있다. 하지만 5와 2 를 한번에 제거할 수 있는 방법은 없으나, amount 초기화 단계를 times() 메서드 안으로 옮겨 보자.

테스트는 여전히 통과하며, 테스트 막대 역시 초록색이다. 하지만, 아직도 중복 데이터는 여전히 존재한다. 다음으로 5라는 값을 제거할 수 있을까?? 이건 생성자를 통해서 넘어오는 값이기 때문에 amount 초기화 단계를 변경해볼 수 있을 것이다.

또한, multiplier 의 값이 2이므로 이것도 중복이며, 상수를 multiplier 로 일반화할 수 있을 것이다.

결과적으로 times 메서드 안에서의 amount 가 변수도 중복이므로 자바 *= 문법을 통해 간결하게 수정할 수 있다.

아직까지 테스트가 성공하는 것을 확인할 수 있다.

이제 드디어 첫 번째 테스트를 완료하며 완료 표시를 할 수 있게 되었다.

  • $5 + 10CHF = $10(환율이 2:1 일 경우)

  • $5 * 2 = 10$

  • amount를 private으로 만들기

  • Dollar 부작용(side effect)?

  • Money 반올림?

요약

요약해보면, 아래와 같이 정리할 수 있다.

  • 자신이 알고 있는 작업해야 할 테스트 목록을 만든다.

  • 오퍼레이션이 외부에서 어떻게 보이길 원하는 지 말해주는 이야기를 테스트 코드로 표현한다.

  • 돌아가는 코드에서 상수를 변수로 변경하여 점진적으로 일반화한다.

  • 새로운 할일을 한번에 처리하는 대신 할일 목록에 추가하고 넘어간다.

Last updated