반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

jUnit 으로 Private Method 테스트 만들기

2013. 6. 10. 08:05 | Posted by 솔웅


반응형

TDD 프로젝트에 join 한지 두달이 넘어갑니다.
이제 Spring Framwork 에서 JUnit 테스트 만드는 일은 제법 익숙해 졌어요.

오늘은 Private 메소드에 대한 JUnit 테스트 만드는 방법을 정리해 두어야 겠습니다.

우선 Method 메소드를 만들어서 테스트할 private 메소드를 담을 겁니다.


Method m = singlePaymentController.getClass().getDeclaredMethod("method name",input parameter -class-);

singlePaymentController 는 테스트할 클래스 이름인데요.


미리 인스턴스를 생성해 놓은 변수 입니다. (SinglePaymentController singlePaymentController = new SinglePaymentController(); 이렇게요.

 

그 클래스에서 getClass()를 안의 getDeclaredMethod() 를 불러 냅니다.
private 메소드를 외부에서 접근할 때는 이 getDeclaredMethod()를 사용하고 private field 에 접근할 때는 getDeclaredField() 나 getDeclaredFields를 사용합니다.


이 밖에서getDeclaredConstructor(), getDeclaredClass() 등 여러가지가 있습니다. 필요할 때 사용하면 됩니다.

 

getDeclaredMethod() 안에 들어가는 인자들은 해당 메소드 이름이 string으로 들어가고 그 다음엔 그 메소드의 input parameter 들을 열거하면 됩니다.

 

그러면 테스트 하고 싶은 private 메소드를 Method 객체 안에 담을 수가 있습니다.

m.setAccessible(true);

 

이제 위 코드 처럼 해당 private 메소드를 접근할 수 있도록 합니다.
이제 외부에서 그 private 메소드에 접근 할 수 있습니다.

 

이제 해당 private method 를 실행시키면 됩니다.


invoke 메소드를 사용하는데요.


그 private method를 담은 Method 객체를 invoke 해 주면 됩니다.
m.invoke() 이렇게요.

 

여기서 invoke 안에는 그 private 메소드가 들어있는 class와 private method 에 전달 될 input parameter 를 넣어 주면 됩니다.

 

private 메소드가 들어있는 클래스는 아까 사용했던 singlePaymentController 가 되겠네요.
그리고 그 private method의 input parameter는 새로 생성해서 테스트 데이터를 넣어 주셔야 됩니다.

 

input parameter 에 필요한 값들 넣기

m.invoke(클래스 이름, input parameter)

 

assert 하기

이렇게해서 해당 private method 안에서 처리되어야 할 값들을 assert 문에 넣어서 예상값과 실제 처리된 값을 비교하면 되겠죠.

 

만약 그 private 메소드가 return 값이 있다면 invoke 해서 return 되는 값을 받아서 그 값을 가지고 assert 하면 됩니다.

 

지금 작업하고 있는 소스를 올릴 수가 없어서 간단하게 따로 만들어 봤습니다.

직접 소스를 보면서 한번 더 익혀 보죠.

 

public class privatemethod

{

private String jUnitPrivate(String a, String b) {

String result = null;

result = a + " : " +b;

return result;

}

}

 

 

아주 간단한 소스 입니다.

그런데 메소드가 private 이죠?

이 메소드에 대한 jUnit test를 만들겠습니다.

 

우선 이 테스트할 클래스에 대한 인스턴스를 생성합니다.

privatemethod jPrivate = new privatemethod();

 

그 다음에는 해당 private 메소드를 담을 Method 객체 생성합니다.

Method m;

 

그리고 이 객체에 해당 private method 를 담습니다.

m = jPrivate.getClass().getDeclaredMethod("jUnitPrivate",String.class,String.class);

 

이제 이 메소드에 대한 접근을 허용해 줍니다.

m.setAccessible(true);

 

그리고 나서 invoke 메소드를 사용해서 이 메소드를 호출합니다.

호출 할 때는 input parameter들을 만들어서 같이 보내 줘야 겠죠?

 

String result =null;

String a = "Korea";

String b = "Seoul";

result = (String) m.invoke(jPrivate,a,b);

 

이제 result 객체에 return 값이 담겼을 테니까 그 결과에 대한 예상값과 실제 값을 가지고 assert 을 해야겠죠.

 

assertEquals("Korea : Seoul",result);

 

이렇게 하고 jUnit 을 돌리면 아래와 같이 녹색을 볼 수 있습니다.

 

 

 

 
완성된 소스는 아래와 같습니다.
 
 
 

public class jUnitPrivateTest

 

{

@Test

public void testJUnitPrivate(){

privatemethod jPrivate = new privatemethod();

Method m;

try

{

m = jPrivate.getClass().getDeclaredMethod("jUnitPrivate",String.class,String.class);

m.setAccessible(true);

String result =null;

String a = "Korea";

String b = "Seoul";

result = (String) m.invoke(jPrivate,a,b);

assertEquals("Korea : Seoul",result);

}

catch (Exception e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

* @throws java.lang.Exception

*/

@BeforeClass

public static void setUpBeforeClass() throws Exception

{

}

/**

* @throws java.lang.Exception

*/

@AfterClass

public static void tearDownAfterClass() throws Exception

{

}

/**

* @throws java.lang.Exception

*/

@Before

public void setUp() throws Exception

{

}

/**

* @throws java.lang.Exception

*/

@After

public void tearDown() throws Exception

{

}

}

 
아래 소스를 다운받으셔서 테스트 해 보셔도 되요.
 
 
privatemethod.java
 
jUnitPrivateTest.java
 
반응형