JUnit으로 private 메소드 테스트하는 방법
개요
Java 테스트 단위로 Junit을 사용되는데, public
메소드 테스트에 대해서는 테스트 코드를 작성하지만, private
, protected
메소드의 테스트는 소홀히 하는 경향있다.
화이트박스 테스트는 프로그래머의 의무를 생각하기에, 모든 코드에 대한 테스트가 필요하다. 그래서 모든 메소드 테스트 실시하는 방법을 설명하겠다.
테스트 소스 코드
먼저 테스트 할 코드를 만들어 보겠다.
Sample.java 파일을 생성하여 아래와 같이 작성하자.
public Sample {
public int add(int x, int y) {
return (x + y);
}
protected int minus(int x, int y) {
return (x - y);
}
private int multiplication(int x, int y) {
return (x * y);
}
}
public 메소드 테스트
그리고 public
메소드 “plus"에 대한 테스트 케이스를 아래와 같이 작성한다.
package com.devkuma.tutorial;
import com.devkuma.tutorial.junit.Calc;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static org.junit.Assert.assertEquals;
public class CalcTest {
public void plus() {
Calc calc = new Calc();
int expected = 7;
int actual = calc.plus(5, 2);
assertEquals(expected, actual);
}
}
간단한 덧셈의 테스트이다. 성공하는 예제만 있는 평범한 테스트 코드이다.
protected, private 메소드 테스트
인스턴스에서는 protected
, private
메소드를 호출할 수 없기 때문에, 자바 리플렉션(reflection)을 이용하여 테스트 케이스를 작성한다.
참고
Sample sample = new Sample();
Method method = Sample.class.getDeclaredMethod("{메소드명}", {인수1}, {인수2}...);
method.setAccessible(true);
int actual = ({반환하는 형})method.invoke(<인스턴스>, {인수1}, {인수2}...);
어느 클래스에도 존재하는 class
변수를 사용하여, getDeclaredMethod()
메소드를 사용하여 테스트 메소드를 가져온다.
반환된 메소드의 setAccessible(true)
을 설정한다. 이는 외부에서 액세스 할 수 있도록하기 위한 설정이다. 그렇다면 method.invoke()
메소드로 테스트 메소드를 실행한다.
위에 작성한 코드에 protected
, private
메소드인 “minus"와 “multiply” 메소드의 테스트 케이스를 추가로 작성해 보자.
package com.devkuma.tutorial;
import com.devkuma.tutorial.junit.Calc;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static org.junit.Assert.assertEquals;
public class CalcTest {
public void plus() {
Calc calc = new Calc();
int expected = 7;
int actual = calc.plus(5, 2);
assertEquals(expected, actual);
}
@Test
public void minus() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Calc calc = new Calc();
int expected = 3;
Method method = Calc.class.getDeclaredMethod("minus", int.class, int.class);
method.setAccessible(true);
int actual = (int) method.invoke(calc, 5, 2);
assertEquals(expected, actual);
}
@Test
public void multiply() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Calc calc = new Calc();
int expected = 10;
Method method = Calc.class.getDeclaredMethod("multiply", int.class, int.class);
method.setAccessible(true);
int actual = (int) method.invoke(calc, 5, 2);
assertEquals(expected, actual);
}
}
결론
이제 작성한 메소드는 모든 테스트 할 수 있게 되었다.
프로그래머가 버그는 최대의 적이다. 가능한 버그를 최대한 제거를 하도록 노력 합시다.