📜 제목으로 보기

  • 내부의 테스트 제어가 안되는 코드(랜덤, 날짜)는 [해당로직을 포함한 메서드]로 추출하고 전략객체.전략메서드()에 위임하고 외부에서 로직을 전달할 수 있게 하여, [테스트에 용이한 다른 전략]으로서 [랜덤 대신 확정값을 가상인자+람다식으로 구현]하여 전략메서드를 구현한다.

image-20220728015130242

메서드내 랜덤로직이 있어서 테스트가 곤란한 경우

image-20220728005109597

자동차 경주 구현

  1. 전략객체에 위임할 로직을 (예비 전략)private메서드로 추출한다. 3e511260-b29a-4cc7-bc03-100d147b2577

  2. **추출한(위임할) 로직전략메서드 구현이므로 구상 전략객체로 넘겨야한다. **

    1. 인터페이스 생성 ->
    2. 구상체 생성 -> 위임 메서드 복붙 ->
    3. 전략 인터페이스로 pull up해서 올려보자.

    2de82b7b-aaf2-4ee8-b24f-495de845fca6

  3. 전략객체는 협력객체로서 메서드인자가 아닌 생성자 주입되는 소유모델이 되어야한다.

    • 파라미터에서 전략객체를 받지말고, 생성자에서 받자.

    d57d101a-f9d5-4d9d-84c5-c581532c329a

  4. 인자로 들어가는 [협력객체]가 [Product용 기본값]이 있는 경우, 오버로딩을 이용해서 내부에서 협력객체 기본값을 강제시킬 수 있다.

    image-20220728012032366

  5. 이제 테스트코드에서는 랜덤전략 대신 실시간 확정 전략을 주입하자.

    • 전략객체.전략메서드()는 1개의 오퍼레이터만 가지는 함수형인터페이스로서 전략메서드를 구상전략객체 없이, (내부 추상체.전략메서드()부분을) 가상인자와 람다식을 통한 실시간 구현이 가능하다

      837ab787-ffd7-4e42-a896-2decc31bec86

      image-20220728011520268

    • 필요하다면, 전략메서드에 확정전략을 구현하는 구상전략객체를 추가해서 대입해줘도 된다.

      • 실시간 구현이 어렵거나, 테스트용 람다식이 아닌 구상체를 선택해야할 경우
  6. 상태를 변화시키는 메서드가, 테스트를 위해 상수 응답하는 getter의 역할까지 하고 있으므로 2메서드를 만들고, return상수응답 로직을 제거 뒤, 테스트에서 객체의 변화된 상태로 비교할 수 있게 수정해본다.

    • eq/hC재정의 후 객체 비교 vs getter구현하여 해당 상태값만 비교할 수 있다.

      • 현재는 전략객체 또한 필드로 들고 있으므로 getter를 따로 생성하여 상태 비교를 하자

      15b8da34-a0c8-47d9-92fa-82bc36933635

    • 비교가 잘되면, 기존 테스드들 원본메서드 -> 2메서드로 수정 + 응답값비교 -> 객체상태값비교로 모두 수정하고 원본 삭제후 2메서드를 원본으로 네이밍한다.

  7. 상태변화 메서드인 .move()는 setter의 상태변화 대신, 상태변화된 객체를 반환하는 메서드로 변경한다.

    1. 객체 자체를 수정하는 것이므로 2객체를 만들어서 테스트해야한다.

    2. move2를 만들고 position++처럼 상태를 변화하는 부분에서 상태변화된 필드로 새 객체를 만들어 반환하도록 수정한다.

      image-20220728024413514

    3. 상태변화하는 필드는 기본값을 주고 생성자에서 안받았기 때문에, 생성자를 추가해주고 필드에는 final을 붙여준다.

      8c73c079-8872-4d88-8284-f7385973688f

      image-20220728024834800

    4. 테스트에서는 자신형 반환 메서드는 체이닝이 가능하므로 체이닝으로 작성해주면 된다.

      • 현재 객체는 협력객체를 포함하고 있어서, 객체끼리 비교가 불가하므로 어쩔 수 없이 getter로 필드를 확인한다.

      image-20220728025404493

    5. 기존의 테스트들(동일 객체 상태비교)을 새 객체반환을 변수로 받아서 상태를 확인하도록 변경한다.

      • 이후, Car의 기존이름을 바꾸고, Car2 -> Car로 변경한다.
  8. 상태변경 메서드(새 객체반환)의 테스트가 끝났으면, 해당 상태로 만들어주는 생성자 추가를고려해서, 다른 테스트에 용이하게 한다.

    image-20220728122259735

    • position 3과 5에 상태로 바로 도달하게끔 생성자를 추가해서, 이미 확정된 객체를 만든다.

      • 이렇게 하면,빈컬렉션+add로직이 컬렉션.of(특정상태,객체들)로 변경된다.

      image-20220728122524465

      image-20220728122511234

      image-20220728122624569

참고 스샷

자동차경주-테스트에서 서비스주입

image-20220728030339975

자동차경주-service로부터 raw결과(list)를 반환시 반환형 ResultView

image-20220728030702845

image-20220728030832105

image-20220728031822882

image-20220728031757141

image-20220728031850384

정리 md(맷)

정리

  • service는 inputview를 알아도 되고, resultview를 반환해도 된다.
  • resultview는 출력을 하기 위해 도메인객체를 input으로 받고, 출력관련 책임만 가진다.
    • 실제 print는 outputview가 하고, resultview는 출력될 요소를 만드는 역할이다.
    • resultview는 유틸메서드로서 string을 반환해준다.
    • racingGame -> resultview에 전달할때는, car list를 반환해주고, 실제 list에서 문자열을 뽑아주는 기능을 사용하는 resultview내부에서 일급컬렉션을 의존사용하고 외부에서 일급컬렉션 생성가능한 파라미터로는 객체가 아닌 재료만받는다.
      • 객체로 메세지를 전달하지만, 1개 객체의 add(create)에서는 재료만받을 수도 있다(객체 조작을 외부에서 꺼내서못하게 할때)
      • 객체list도 객체라서 굳이 일급컬렉션을 외부에서 사용안할때 생성할필요는 없다?