Eclipse Eclipse 방식으로 단위 테스팅 하기

황제낙엽 2007.10.03 07:26 조회 수 : 69 추천:94

sitelink1  
sitelink2  
sitelink3  
http://www.ibm.com/developerworks/kr/library/os-eclipse-rmock/index.html

Eclipse IDE에서 자바용 RMock 테스팅 프레임웍으로 jMock 강화하기

developerWorks
문서 옵션
수평출력으로 설정

이 페이지 출력

이 페이지를 이메일로 보내기

이 페이지를 이메일로 보내기

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

영어원문

영어원문

?
제안 및 의견
피드백

난이도 : 중급

Michael Nyika, Software Engineer, MichaelDKelly.com

2007 년 7 월 24 일

소스 코드 베이스를 테스트 할 수 있는 적합한 테스트 슈트가 필요하십니까? jMock은 훌륭한 테스팅 프레임웍으로서 자격을 갖추었습니다. 하지만 모든 상황에jMock이 다 맞는 것은 아닙니다. 애플리케이션에서 단위 테스트를 지원하는 커스텀 mock 객체를 어렵게 만들 필요 없이, RMock이 jMock과 조화롭게 작동하도록 하여 긍정적인 결과를 얻을 수 있습니다.
소셜 북마크

mar.gar.in mar.gar.in
digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

Mock 객체들은 클래스의 작동을 모방하여 클래스들이 테스트를 받을 수 있도록 한다. mock 객체들의 수는 애플리케이션 클래스의 수만큼 증가할 수 있다. jMock, RMock, EasyMock은 물리적이고 개별적으로 존재하는 mock 객체들에 대한 필요성을 줄인다.

EasyMock 프레임웍의 큰 단점 중 하나는 구체적인 클래스를 모방할 수 없다는 점이다. ? 오직 인터페이스만 가능하다. 이 글에서, jMock 프레임웍을 사용하여 구체적인 클래스 인터페이스를 모방하는 방법과 RMock으로 특정 모호한 케이스들을 테스트 하는 방법을 설명하겠다.


Eclipse 플랫폼은 jMock과 RMock 테스팅 프레임웍을 쉽게 사용할 수 있는 메커니즘을 제공합니다.

Eclipse IDE에 jMock과 RMock 설정하기

주: JUnit, jMock, RMock의 최신 바이너리는 참고자료 섹션을 참조하라.

Eclipse 통합 개발 환경(IDE)를 시작한다. JUnit, jMock, RMock Java Archive (JAR) 라이브러리를 가져올 기본 자바™ 프로젝트를 만든다. 자바 프로젝트의 이름을 TestingExample로 한다. 자바 퍼스펙티브에서, Project > Properties를 선택하고 Libraries 탭을 클릭한다.


그림 1. Eclipse의 TestingExample 프로젝트용 편집 프로퍼티
Eclipse의 TestingExample 프로젝트용 편집 프로퍼티

JAR 파일들이 Java classpath (다시 말해서, Eclipse 내에 설정했던 Java Runtime Environment (JRE))에 있을 때 Add JARs 버튼을 사용한다. Add Variable 버튼은 파일 시스템(로컬 또는 원격)에 있는 (JAR를 포함한)리소스들이 상주할 특정 디렉토리에 적용되고 일반적으로 참조될 수 있다. Eclipse에서 기본이고 특정 Eclipse 워크스페이스 환경을 위해 설정된 특정 리소스를 참조해야 할 때 Add Library 버튼을 사용한다. Add Class Folder를 클릭하여 프로젝트의 일부로서 이미 설정된 기존 프로젝트 폴더들 중 하나에서 리소스를 추가한다.

예를 들어, Add External JARs를 클릭하고, 다운로드 했던 jMock과 RMock JAR를 검색한다. 이들을 프로젝트에 추가한다. 그림 2와 같은 프로퍼티 창이 나타나면 OK를 클릭한다.


그림 2. TestingExample Project에 추가된 jMock과 RMock JAR
TestingExample Project에 추가된 jMock과 RMock JAR




위로


TestExample 소스 코드

TestExample Project의 경우, 네 개의 클래스에서 소스 코드로 작업해야 한다.

  • ServiceClass.java
  • Collaborator.java
  • ICollaborator.java
  • ServiceClassTest.java

테스트 시 클래스는 ServiceClass가 될 것이다. 여기에는 하나의 메소드 runService()가 포함된다. 이 서비스 메소드는 Collaborator라고 하는 객체를 취하는데, 이는 인터페이스인 ICollaborator를 구현한다. 하나의 메소드가 구체적인 Collaborator 클래스인 executeJob()에 구현된다. Collaborator는 여러분이 올바르게 모방해야 하는 클래스이다.

네 번째 클래스는 테스트 클래스, ServiceClassTest이다. (구현은 가능한 단순하게 유지한다.) Listing 1은 네 번째 클래스에 대한 코드 모습이다.


Listing 1. 서비스 클래스 샘플 코드

·미리보기 | 소스복사·
  1. public class ServiceClass {   
  2.     public ServiceClass(){   
  3.     //no-args constructor      
  4.     }   
  5.   
  6.     public boolean runService(ICollaborator collaborator){   
  7.     if("success".equals(collaborator.executeJob())){   
  8.         return true;   
  9.     }   
  10.     else  
  11.     {   
  12.         return false;   
  13.     }   
  14. }   
  15. }  

ServiceClass 클래스에서, if...else 코드 블록은 경로가 테스트 기대값에 따라 취해질 경우 실패 또는 성공했는지의 이유를 보여주는 단순한 논리적 교차점이다. Collaborator 클래스용 소스 코드는 다음과 같다.


Listing 2. Collaborator 클래스 샘플 코드

·미리보기 | 소스복사·
  1. public class Collaborator implements ICollaborator{   
  2.    public Collaborator(){   
  3.        //no-args constructor   
  4.    }   
  5.    public String executeJob(){   
  6.        return "success";   
  7.    }   
  8. }  

Collaborator 클래스 역시 단순하다. 인자 생성자가 없고, executeJob() 메소드에서 리턴된 단순한 String이 있을 뿐이다. 아래 코드는 ICollaborator 클래스용 코드를 보여주고 있다.

·미리보기 | 소스복사·
  1. public interface ICollaborator {   
  2.     public abstract String executeJob();   
  3. }  

ICollaborator 인터페이스는 Collaborator 클래스에서 구현되어야 하는 단일 메소드를 갖고 있다.

이제 다른 시나리오에서 ServiceClass 클래스를 성공적으로 테스트 하는 방법에 대해 알아보자.




위로


시나리오 1: jMock을 사용하여 인터페이스 모방하기

ServiceClass 클래스에서 서비스 메소드를 테스트 하는 것은 간단하다. 테스트 요구 사항이 runService() 메소드가 실행되지 않았다는 것을 선언하는 것이라면, 다시 말해서, Boolean 결과가 false일 경우를 생각해보자. 이와 같은 경우에, runService() 메소드로 전달된 ICollaborator 객체는 이것의 메소드인 executeJob()에 대한 호출이 기다리고 "success"외 다른 스트링을 리턴하는 것으로 모방된다. 이러한 방식으로, Boolean 스트링 false가 테스트로 리턴되는 것을 볼 수 있다.

ServiceClassTest 클래스용 코드에는 테스트 로직이 포함되어 있다.


Listing 3. 시나리오 1에 대한 ServiceClassTest 클래스 샘플 코드
                
·미리보기 | 소스복사·
  1. import org.jmock.Mock;   
  2. import org.jmock.cglib.MockObjectTestCase;   
  3. public class ServiceClassTest extends MockObjectTestCase {   
  4.     private ServiceClass serviceClass;   
  5.     private Mock mockCollaborator;   
  6.     private ICollaborator collaborator;   
  7.        
  8.     public void setUp(){   
  9.         serviceClass = new ServiceClass();   
  10.         mockCollaborator = new Mock(ICollaborator.class);   
  11.     }   
  12.        
  13.     public void testRunServiceAndReturnFalse(){   
  14.         mockCollaborator.expects(once()).method   
  15.               ("executeJob").will(returnValue("failure"));   
  16.         collaborator = (ICollaborator)mockCollaborator.proxy();   
  17.         boolean result = serviceClass.runService(collaborator);   
  18.         assertFalse(result);   
  19.     }   
  20. }  

테스트를 작성할 때

테스트 mock 프레임웍에서 실행하는 최상의 방법은 테스트 우선의 신속한 방식을 사용하는 것이다. 테스트를 먼저 만들고 기대값을 설정한다. 테스트가 실패한 후에야, 테스트를 수정 할 구현을 작성한다. 테스트가 작동하면, 또 다른 테스트를 작성하여 나중에 테스트 시 클래스에 추가한 기능을 검사한다.

다양한 테스트 케이스들에 일반 연산들이 수행되어야 한다면 테스트에 setUp() 메소드를 포함시키는 것도 좋은 생각이다. tearDown() 메소드 역시 좋은 생각이지만, 통합 테스트를 수행하고 있는 것이 아니라면 꼭 그럴 필요가 없다.

jMock과 RMock을 사용할 때, 프레임웍은 테스트 실행 끝과 중간에 모든 mock 객체들에 대한 기대값을 검사한다. 각 mock의 기대값에 verify() 메소드를 포함시킬 필요는 없다. JUnit 테스트로서 실행할 때, 테스트는 성공한다.


그림 3. 시나리오1 테스트 통과
시나리오1 테스트 통과

ServiceTestClass 클래스는 jMock CGLIB의 org.jmock.cglib.MockObjectTestCase 클래스를 확장한 것이다. mockCollaborator는 간단한 org.jmock.JMock 클래스이다. 일반적으로, jMock으로 mock 객체들을 만드는 두 가지 방법이 있다.

  • 인터페이스를 모방하려면 new Mock(Class.class) 메소드를 사용한다.
  • 구체적 클래스를 모방하려면, mock(Class.class, "identifier") 메소드를 사용한다.

ServiceClass 클래스의 runService() 메소드로 mock proxy가 전달되는 방식을 알아두는 것이 중요하다. jMock을 사용하여, 생성된 mock 객체들에서 프록시 구현들을 추출할 수 있다. 여기에서 기대값이 이미 설정되었다. 이 부분은 다음 시나리오에서 매우 중요한 것이다. RMock이 관여할 경우 특히 그렇다.




위로


시나리오 2: jMock을 사용하여 기본 생 성자를 가진 구체적 클래스 모방하기

ServiceClassrunService() 메소드가 Collaborator Collaborator 클래스의 구체 구현만 수락한다고 가정해 보자. jMock은 기대값을 변경하지 않고 이전의 테스트를 통과시킬 정도로 충분한가? 간단하고 기본적인 방식으로 Collaborator 클래스를 구현할 수 있는 한 그렇다.

ServiceClass 클래스의 runService() 메소드를 수정하여 아래 코드를 반영해 보자.


Listing 4. 시나리오 2를 위해 편집된 ServiceClass 클래스
                
·미리보기 | 소스복사·
  1. public class ServiceClass {   
  2.     public ServiceClass(){   
  3.     //no-args constructor      
  4.     }   
  5.   
  6. public boolean runService(Collaborator collaborator){   
  7.     if("success".equals(collaborator.executeJob())){   
  8.         return true;   
  9.     }   
  10.     else{   
  11.         return false;   
  12.     }   
  13. }   
  14. }  

ServiceClass 클래스의 if...else 로직 브랜치는 같다. 또한, 무 인자(no-arguments) 생성자 역시 적소에 있다. while...do 문이나 for 루프 같은 로직이 클래스의 메소드를 테스트하게 할 필요는 없다. 클래스가 사용하는 객체에 대한 메소드 실행이 있는 한, 간단한 mock 기대치로 그러한 실행들을 테스트할 수 있다.

ServiceClassTest 클래스를 수정하여 시나리오에 맞출 수 있다.


Listing 5. 시나리오 2를 위해 편집된 ServiceClassTest 클래스
                
·미리보기 | 소스복사·
  1. ...   
  2. private ServiceClass serviceClass;   
  3.     private Mock mockCollaborator;   
  4.     private Collaborator collaborator;   
  5.        
  6.     public void setUp(){   
  7.         serviceClass = new ServiceClass();   
  8.         mockCollaborator = mock(Collaborator.class"mockCollaborator");   
  9.     }   
  10.        
  11.     public void testRunServiceAndReturnFalse(){   
  12.         mockCollaborator.expects(once()).method("executeJob").will(returnValue("failure"));   
  13.         collaborator = (Collaborator)mockCollaborator.proxy();   
  14.         boolean result = serviceClass.runService(collaborator);   
  15.         assertFalse(result);   
  16.     }   
  17. }  

여기에서 주목해야 할 몇 가지 포인트가 있다. 우선, runService() 메소드 서명은 이전에 비하여 바뀌었다. ICollaborator 인터페이스를 수락하는 대신, 이제는, 구체적 클래스 구현(Collaborator 클래스)를 수락한다. 이러한 변화는 테스팅 프레임웍이 관여되어 있는 한 중요하다. (비 다형성이라는 특징이 있지만, 예제를 위해서 구체적인 클래스를 전달하는 예제를 사용한다. 실제 객체 지향 방식으로는 수행되어서는 안된다.)

두 번째, Collaborator 클래스를 모방하는 방식이 바뀌었다. jMock CGLIB 라이브러리는 구체적인 클래스 구현을 모방할 수 있다. jMock CGLIB의 mock() 메소드에 제공된 여분의 String 매개변수는 생성된 mock() 객체용 식별자로서 사용된다. jMock(그리고 실제로 RMock)을 사용할 때, 하나의 테스트 케이스 내에 mock 객체 설정마다 고유 식별자가 필요하다. 이는 일반 setUp() 메소드 또는 실제 테스트 메소드에서 정의된 mock 객체들도 마찬가지다.

세 번째로, 테스트 메소드의 원래 기대값은 바뀌지 않았다. 테스트를 통과시키기 위해서 false 선언이 여전히 필요하다. 일정한 테스트 결과를 허용하면서, 다른 인풋에 대한 변화를 수용할 정도로 테스팅 프레임웍이 유연하다는 것을 보여줌으로써, 같은 결과를 만들어 내기 위해 인풋이 수용될 수 없을 때 진정한 한계가 나타나기 때문에 중요하다.

이제, JUnit 테스트로서 테스트를 재실행 한다. 테스트는 아래와 같이 통과한다.


그림 4. 시나리오 2 테스트 통과
시나리오 2 테스트 통과

다음 시나리오에서, 상황은 약간 더 복잡해졌다. RMock 프레임웍을 사용하여 어려운 상황처럼 보이는 것을 제거한다.




위로


시나리오 3: jMock과 RMock을 사용하여 특정 생성자를 가진 구체적 클래스 모방하기

전처럼, jMock을 사용하여 Collaborator 객체를 모방하는 것으로 시작한다. Collaborator는 기본적인 무 인자 생성자를 갖고 있지 않다. 불린 false 결과의 테스트 기대값이 유지된다.

또한, Collaborator 객체는 생성자로 전달된 매개변수로서 하나의 스트링과 프리머티브 int를 필요로 한다. Listing 6은 Collaborator 객체에 생긴 변화이다.


Listing 6. 시나리오 3에서 변경된 Collaborator 클래스
                
·미리보기 | 소스복사·
  1. public class Collaborator{   
  2.    private String collaboratorString;   
  3.    private int collaboratorInt;   
  4.        
  5.    public Collaborator(String string, int number){   
  6.        collaboratorString = string;   
  7.        collaboratorInt = number;   
  8.    }   
  9.    public String executeJob(){   
  10.     return "success";   
  11.   }   
  12. }  

Collaborator 클래스 생성자는 여전히 간단하다. 클래스 필드는 인커밍 매개변수로 설정된다. 다른 로직은 여기에서는 필요하지 않고, executeJob() 함수도 같다.

예제의 다른 모든 컴포넌트로 테스트를 재실행 한다. 결과는 끔찍한 테스트 오류이다.


그림 5. 시나리오 3 테스트 오류
시나리오 3 테스트 오류

위 테스트는 코드 커버리지 없이 간단한 JUnit 테스트로서 실행되었다. 코드 커버리지 툴(Cobertura 또는 EclEmma) 을 사용하여 이 글에 리스팅 된 테스트를 실행할 수 있다. 하지만, Eclipse에서 코드 커버리지로 RMock 테스트를 실행할 때 몇 가지 문제가 있다. (표 1) 아래 코드는 실제 스택 트레이스 모습이다.


Listing 7. 시나리오 3에서 테스트 오류에 대한 스택 트레이스
                
·미리보기 | 소스복사·
  1.                ...Superclass has no null constructors but no arguments were given   
  2. at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:718)   
  3. at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)   
  4. at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)   
  5. at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)   
  6. at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)   
  7. at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)   
  8. at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:660)   
  9. .....   
  10. .....   

오류 이유는 jMock이 무 인자 생성자가 없는 클래스 정의에서 가능한 mock 객체를 만들 수 없기 때문이다. Collaborator 객체를 인스턴스화 하는 유일한 방법은 두 개의 간단한 인자를 제공하는 것이다. 여러분은 이제 mock 객체 인스턴스화 과정에 대한 인자가 같은 효과를 내는 방법을 찾아야 한다. 바로 이것이 RMock을 사용하는 이유이다.

RMock 테스팅 프레임웍에서 실패한 테스트 정정하기

테스트를 정정하려면, 몇 가지 수정이 필요하다. 미묘한 것처럼 보이지만, 실제로는 두 프레임웍들의 힘을 활용하는 간단한 해결책이다.

첫 번째 필요한 변화는 테스트 클래스를 jMock CGLIB TestCase가 아닌 RMock TestCase로 만드는 것이다. 이렇게 하는 이유는 테스트 내의 RMock에 속한 mock 객체들을 초기 설정 시 더욱 쉽게 설정하기 위함이다. 테스트 클래스의 확장 기반인 TestCase 객체가 RMock에 속해있다면 두 프레임웍들에서 mock 객체들을 구현 및 사용하는 것이 더 쉽다. 더욱이, mock 객체들의 흐름을 빠르게 결정하기에도 더 쉽다. (여기에서 플로우는 mock 객체를 매개변수로서 사용하고, 다른 mock 객체들의 리턴 유형으로서 사용하는 상황을 설명하기 위해 사용된다.)

두 번째 변화는 Collaborator 클래스의 생성자로 전달된 실제 매개변수의 값을 보유하고 있는 객체 어레이를 구현하는 것이다. 생성자가 수락하는 클래스 유형 어레이를 포함시키고, 매개변수로서 기술된 객체 어레이 mock Collaborator 객체를 인스턴스화 하기 위해 그 어레이를 전달하는 것도 가능하다.

세 번째 변화는 정확한 신택스를 가진 RMock mock 객체에 대한 한 개 이상의 예외를 구현하는 것이다. 네 번째와 마지막 변화는 기록 상태의 RMock mock 객체를 준비 상태로 가져오는 것이다.

RMock의 변경 내용을 구현하기

Listing 9는 ServiceClassTest 클래스에 대한 마지막 수정 모습이다. RMock과 관련 기능의 도입에 대해 나타내고 있다.


Listing 9. 시나리오 3에서 ServiceClassTest 수정하기


·미리보기 | 소스복사·
  1. ...   
  2. import com.agical.rmock.extension.junit.RMockTestCase;   
  3. public class ServiceClassTest extends RMockTestCase {   
  4.   
  5.     private ServiceClass serviceClass;   
  6.     private Collaborator collaborator;   
  7.        
  8.     public void setUp(){   
  9.         serviceClass = new ServiceClass();   
  10.         Object[] objectArray = new Object[]{"exampleString", 5};   
  11.                 collaborator =   
  12.                 (Collaborator)intercept(Collaborator.class, objectArray, "mockCollaborator");   
  13.     }   
  14.        
  15.     public void testRunServiceAndReturnFalse(){   
  16.         collaborator.executeJob();   
  17.         modify().returnValue("failure");   
  18.         startVerification();   
  19.         boolean result = serviceClass.runService(collaborator);   
  20.         assertFalse(result);   
  21.     }   
  22. }  




먼저, 테스트의 기대값은 여전히 변하지 않았다. RMockTestCase 클래스의 반입은 RMock 프레임웍 기능의 도입을 나타낸다. 그 다음, 테스트 클래스는 이제, MockObjectTestCase 보다는 RMockTestCase를 확장한다. 나중에, TestClass 객체가 여전히 RMockTestCase 객체의 유형인 테스트 케이스 내의 MockObjectTestCase의 재도입에 대해 설명하겠다.

intercept() 메소드에 대한 대안

RMock의 경우, intercept() 메소드를 사용해서는 구체적인 클래스만 모방할 수 있다. RMock mock() 메소드를 사용하여 구체적인 클래스와 인터페이스를 모방할 수 있다. 소수의 메소드만 모방해야 할 때, interface() 메소드를 사용하라. 이 메소드를 mock() 메소드로 간주하라.

setUp() 메소드 내에서, Collaborator 클래스의 생성자가 필요로 하는 실제 값으로 객체 어레이를 인스턴스화 한다. 이 어레이는 RMock의 intercept() 메소드로 들어가서 mock 객체의 인스턴스화를 돕는다. 메소드의 서명은 jMock CGLIB mock() 메소드의 서명과 비슷하다. 두 메소드 모두 인자로서 고유 mock 객체 식별자를 취하기 때문이다. Collaborator 유형으로의 mock 객체의 클래스 캐스트는 필요하다. intercept() 메소드가 Object 유형을 리턴하기 때문이다.

테스트 메소드, testRunServiceAndReturnFalse()에서, 몇 가지 변화를 볼 수 있다. mock Collaborator 객체의 executeJob() 메소드가 호출된다. 이 단계에서, mock 객체는 기록 상태(record state)에 있다. 다시 말해서, 기대하는 메소드 호출을 정의한다. 따라서, mock은 이에 따른 기대값을 기록한다. 다음 라인은 mock 객체에 대한 공지로서, 이것인 executeJob() 메소드를 만날 때, failure 스트링을 리턴 하도록 한다. 따라서, RMock에서는 mock 객체에서 메소드를 호출함으로써(그리고 필요한 매개변수를 전달하여) 기대 값을 나타내고, 이에 따라 기대값을 수정하여 리턴 유형을 조정한다.

마지막으로, RMock 메소드 startVerification()은 mock Collaborator 객체를 준비 상태(ready state)로 만들기 위해 호출된다. 이 mock 객체는 실제 객체로서 ServiceClass 클래스에서 사용할 준비가 된다. 이 메소드는 매우 필수적인 것이며 테스트 초기화 오류를 피하기 위해 호출되어야 한다.

변경 사항 테스트 하기

ServiceClassTest를 다시 한번 재실행 하여 마지막으로 긍정적인 결과를 이룩한다. 여러분이 mock 객체 인스턴스화 과정 동안 제공했던 매개변수들이 이 모든 차이를 만든다. 그림 6은 성공을 나타내는 연두색을 보여주고 있다.


그림 6. RMock에서 시나리오 3의 테스트 성공
RMock에서 시나리오 3의 테스트 성공

assertFalse(result) 코드 라인은 시나리오 1의 같은 테스트 기대값을 나타내고, RMock은 jMock이 앞서 이룩했던 테스트 성공을 이루었다. 여러 가지 면에서 중요하지만, 가장 중요한 것은 테스트 기대값을 바꾸지 않고 실패한 테스트를 수정하는 애자일(agile) 원리가 적용되었다는 점이다. 유일한 차이는 대안 프레임웍이 사용되었다는 점이다.

다음 시나리오에서는, jMock과 RMock을 특별한 케이스에 사용할 것이다. 테스트 내의 동맹이 형성되지 않는 한 올바른 결과를 만들어 낼 수 없다.




위로


시나리오 4: jMock과 RMock의 특별한 협업

앞서 언급했듯이, 두 개의 프레임웍들이 협력하여 특정 결과를 만들어 내는 케이스를 연구해야 했다. 그렇지 않았다면, 잘 만들어진 테스트도 매번 실패했을 것이다. jMock을 사용하든 RMock을 사용하든 문제가 되지 않는 상황이 있다. 이러한 상황에서는, 모방하고자 하는 인터페이스나 클래스가 서명이 되어 있는 JAR에 존재한다. 하지만 이 같은 상황은 극히 드물고, 테스팅 코드가 안전한 상용 제품들의 애플리케이션 프로그래밍 인터페이스(API)에 작성되었을 때 발생한다.

Listing 10은 두 프레임웍이 테스트 케이스를 실행하는 예제를 보여주고 있다.


Listing 10. 시나리오 4의 테스트 예제

·미리보기 | 소스복사·
  1. public class MyNewClassTest extends RMockTestCase{   
  2.   
  3. private MyNewClass myClass;   
  4. private MockObjectTestCase testCase;   
  5. private Collaborator collaborator;   
  6. private Mock mockClassB;   
  7.   
  8.     public void setUp(){   
  9.         myClass = new MyNewClass();   
  10.   
  11.         testCase = new MyMockObjectTestCase();   
  12.   
  13.         mockClassB = testCase.mock(ClassB.class"mockClassB");   
  14.         mockClassB.expects(testCase.once()).method("wierdMethod").   
  15.                 will(testCase.returnValue("passed"));   
  16.   
  17.         Class[] someClassArray = new Class[]{String.class, ClassA.class, ClassB.class};   
  18.         Object[] someObjectArray = new Object[]   
  19.             {"someArbitraryString"new ClassA(), (ClassB)mockClassB.proxy()};   
  20.   
  21.         collaborator = (Collaborator)intercept   
  22.                 (Collaborator.class, someClassArray, someObjectArray, "mockCollaborator");   
  23.     }   
  24.   
  25.     public void testRMockAndJMockInCollaboration(){   
  26.         startVerification();   
  27.         assertTrue(myClass.executeJob(collaborator));   
  28.     }   
  29.   
  30.     private class MyMockObjectTestCase extends MockObjectTestCase{}   
  31.   
  32.     private class MyNewClass{   
  33.         public boolean executeJob(Collaborator collaborator){   
  34.             collaborator.executeSomeImportantFunction();   
  35.             return true;   
  36.         }   
  37.     }   
  38. }   


setUp() 메소드에서, 새로운 "testcase"가 jMock-CGLIB MockObjectTestCase 객체를 확장하기 위해 생성된 프라이빗 내부 클래스에 기반하여 인스턴스화 된다. 이러한

번호 제목 글쓴이 날짜 조회 수
38 VSS Plugin version for Eclipse file 황제낙엽 2010.09.29 82
37 eclipse 3.5(Galileo)에서 SVN 사용하기 황제낙엽 2009.11.02 99
36 eclipse에서 JVM terminated. Exit code=-1 file 황제낙엽 2009.02.13 26
35 프로퍼티 파일(application.properties)의 유니코드 변환(native2ascii) 에디터 플러그인 황제낙엽 2005.12.20 46
34 JadClipse Eclipse Europa 버젼에서 쓰기 (펌) file 황제낙엽 2008.07.30 67
33 Eclipse에 웹로직 9.2 설정하기 황제낙엽 2008.04.30 139
» Eclipse 방식으로 단위 테스팅 하기 황제낙엽 2007.10.03 69
31 Eclipse 3.0 (이클립스) - 자주 사용하는 기본 기능들 및 단축키 황제낙엽 2005.11.11 72
30 코드 포맷팅 기능 사용하기 황제낙엽 2007.07.27 51
29 디버깅(Debugging) 기능 사용하기 황제낙엽 2007.07.27 99
28 리팩토링의 인라인(Inline) 기능에 대해서 황제낙엽 2007.07.27 39
27 리팩토링 (Refactoring) 사용하기 황제낙엽 2007.07.27 2803
26 코드 템플릿을 이용한 Javadoc 황제낙엽 2007.07.27 128
25 Eclipse 3.0 (이클립스) - 알아두면 좋은 유용한 단축키 모음 황제낙엽 2007.07.19 94
24 디버깅(debuging)시 잘못된 경로에서 소스를 찾게 되는 경우 황제낙엽 2007.06.04 82
23 이클립스에서 생성한 Default Java Project를 Dynamic Web Project 로 변신시키기 file 황제낙엽 2007.04.19 173
22 Eclipse 성능높이기 황제낙엽 2007.04.12 25
21 TPTP 를 이용한 자바 어플리케이션 프로파일링 file 황제낙엽 2007.04.12 64
20 Ecipse & UML file 황제낙엽 2007.04.12 80
19 Eclipse 인터페이스는 영문, 도움말은 한글로 보기 황제낙엽 2007.03.07 489