TDD 주기는 다음과 같다.

  1. 테스트를 작성한다. 마음속에 있는 오퍼레이션이 코드에 어떤 식으로 나타나길 원하는지 생각해봐라. 원하는 인터페이스를 개발해라. 올바른 답을 얻기 위해 필요한 이야기의 모든 요소를 포함 시켜라.
  2. 실행 가능하게 만든다. 일단 테스트 통과시키는 것이 중요하다. 깔끔하고 단순한 해법이 명백히 보이면 그것을 입력해라. 만약 깔끔하고 단순한 해법이 있지만 구현하는 데 몇 분 정도 걸릴 것 같다면 일단 적어 놓은 뒤에 원래 문제로 돌아오자.
  3. 올바르게 만든다. 시스템이 이제 작동하므로 직전에 저질렀던 죄악을 수습하자. 중복을 제거하고 테스트가 통과되게 만들자.

목적은 작동하는 깔끔한 코드를 얻는 것이다.

하지만 그것은 도달하기 힘들기 때문에 나누어서 정복하자 (divide and conquer)

일단 ‘작동’ 하게 만들고 → ‘깔끔한 코드’ 부분을 해결해라.

‘깔끔한 코드’ 부분을 해결한 후에 ‘작동하는’ 부분을 해결해 나가면서 배운 것들을 설계에 반영하느라 허둥거리는 아키텍처 주도 개발 (architecture-driven development)과는 정 반대다.

[목록]

Dollar side effect:

@Test
    void testMultiplication() {
        Dollar five = new Dollar(5);
        five.times(2);
        assertThat(five.amount).isEqualTo(10);
        five.times(3);
        assertThat(five.amount).isEqualTo(15);
    }

위 방법에서 test() 에서 새로운 객체를 반환하게 하면 어떨까?