Working Effectively With Legacy Code 내용 중에 테스트 가능한 프로그래밍 기법이 있는데, 재밌는 예제였습니다.
올바른 값을 가져오는지 테스트하기 위해서 탐침(probe)과도 같은 클래스를 만들어냅니다. 보통 메소드 안에서 흘러가는 흐름을 테스트 때문에 감지를 위한 것이지요.
public void 급정거(int level) {
// ...
System.out.println("버럭! "+level+"번");
// ...
}
}
저 부분을 테스트하기 위해서 코드를 분리합니다.
public void 급정거(int level) {
// ...
CarSpeaker speaker = new CarSpeaker();
speaker.yell("버럭! "+level+"번");
// ...
}
}
CarSpeaker 는 내용을 감지하기 위한 미끼역할을 하게 됩니다.
System.out.println(string);
}
테스트를 위해서 인터페이스를 뽑아냅니다.
System.out.println(string);
}
public void yell(String string);
}
그리고 speaker를 외부에서 지정할 수 있도록 필드로 만듭니다. 지정은 생성자에서 담당합니다.
private Speaker speaker;
public Car(Speaker speaker) {
this.speaker = speaker;
}
public void 급정거(int level) {
// ...
speaker.yell("버럭! "+level+"번");
// ...
}
}
이렇게 코드의 구성이 끝나면 감지를 전담하는 FakeSpeaker를 만들 수 있습니다.
String string;
this.string = string;
}
public String getString() {
return string;
}
테스트케이스는 다음과 같이 됩니다.
public void test급정거() {
FakeSpeaker speaker = new FakeSpeaker();
Car car = new Car(speaker);
car.급정거(1);
assertEquals("버럭! 1번", speaker.getString());
}
}
처음 코드 보다 설계는 복잡해졌지만, 테스트를 자동화하는 효과를 얻었습니다.
선택의 시간입니다. 그냥 System.out.println(">>>>"+level); 로 원본 클래스를 바꿔서 테스트할 것입니까, 아니면 테스트 케이스를 위해서 소스 코드의 설계를 바꿔서 하시겠습니까.
참고자료
Working Effectively With Legacy Code, Michael C. Features, Prentice Hall, P23-28
까오기님이 정리한 글
http://kkaok.pe.kr/servlet/KBoard?cmd=view&tableName=kmytip&flag=0&search=&findword=&gotoPage=1&seq=124