달력

102021  이전 다음

  •  
  •  
  •  
  •  
  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  •  
  •  
  •  
  •  
  •  
  •  

'Injection'에 해당되는 글 1건

  1. 2007.12.11 감지하기 그리고 분리하기 (8)

Working Effectively With Legacy Code 내용 중에 테스트 가능한 프로그래밍 기법이 있는데, 재밌는 예제였습니다.
올바른 값을 가져오는지 테스트하기 위해서 탐침(probe)과도 같은 클래스를 만들어냅니다. 보통 메소드 안에서 흘러가는 흐름을 테스트 때문에 감지를 위한 것이지요.

package net.okjsp;
public class Car {
 public void 급정거(int level) {
  // ...
  System.out.println("버럭! "+level+"번");
  // ...
 }
}

저 부분을 테스트하기 위해서 코드를 분리합니다.

package net.okjsp;
public class Car {
 public void 급정거(int level) {
  // ...
  CarSpeaker speaker = new CarSpeaker();
  speaker.yell("버럭! "+level+"번");

  // ...
 }
}

CarSpeaker 는 내용을 감지하기 위한 미끼역할을 하게 됩니다.
package net.okjsp;
public class CarSpeaker {
 public void yell(String string) {
  System.out.println(string);
 }
}

테스트를 위해서 인터페이스를 뽑아냅니다.
package net.okjsp;
public class CarSpeaker implements Speaker {
 public void yell(String string) {
  System.out.println(string);
 }
}

package net.okjsp;
public interface Speaker {
 public void yell(String string);
}


그리고 speaker를 외부에서 지정할 수 있도록 필드로 만듭니다. 지정은 생성자에서 담당합니다.
package net.okjsp;
public class Car {
 private Speaker speaker;
 
 public Car(Speaker speaker) {
  this.speaker = speaker;
 }
 
 public void 급정거(int level) {
  // ...
  speaker.yell("버럭! "+level+"번");
  // ...
 }
}

이렇게 코드의 구성이 끝나면 감지를 전담하는 FakeSpeaker를 만들 수 있습니다.
package net.okjsp;
public class FakeSpeaker implements Speaker {
 String string;
 public void yell(String string) {
  this.string = string;
 }

 
 public String getString() {
  return string;
 }
}

테스트케이스는 다음과 같이 됩니다.
package net.okjsp;
import junit.framework.TestCase;
public class CarTest extends TestCase {
 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
Posted by 케누 kenu허광남

댓글을 달아 주세요

  1. CoolGuy  댓글주소 수정/삭제 댓글쓰기 2007.12.12 09:11

    좋은글 감사합니다.
    따라해 봐야겠네요 ^^

  2. pungjoo  댓글주소 수정/삭제 댓글쓰기 2007.12.12 10:13

    good..!

  3. 보리  댓글주소 수정/삭제 댓글쓰기 2007.12.12 14:44

    좋은글 감사합니다.. ^^

  4. 하수개발  댓글주소 수정/삭제 댓글쓰기 2007.12.14 17:53

    다형성을 이용한 패턴적용은 만들어 진걸 보면 참 멋지고 이해가 잘되는데
    왜!!! 설계할때는 저리 안그려지는 건지..-_-;

  5. 하수개발  댓글주소 수정/삭제 댓글쓰기 2007.12.14 18:03

    아참 본문과는 상관 없는 질문 인데요.
    저번에 Refact 신촌에서 세미나 진행 하실때 작성 하셨던 ppt자료는 어디에 있는건가요?
    링크를 잃어 버려서요 ^^;.
    전에 작업 하시던거 보고 바로 유로파 깔아서 테스트 해보고 있는데 참고좀 하려구요.
    이야기 하시던거 적어 가지 못한게 몇가지 있어서 그거 보면서 하면 기억이 좀 날까 하네요.