서론

private method도 테스트 해야되는지에 대해선 의견이 많은 것으로 알고 있지만 현재 프로젝트에서 service에서 있는 메서드 중 주요 로직은 private method에 존재하고 public method에선 호출해서 return만 해주는 method가 존재했는데, 이런 경우에 private 메서드를 테스트하기 위한 방법을 정리해둔다.


본론

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Test
void getPassAndFailWordList_성공() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//given
String[] answerIds = new String[] {"6_1", "4_1", "5_1", "9_3"};
WordService w = new WordServiceImpl(repository, userService);

Method method = w.getClass().getDeclaredMethod("getPassAndFailWordList", String[].class);
method.setAccessible(true);

List<Integer> passWordList = Arrays.asList(6,4,5);
List<Integer> failWordList = Arrays.asList(9);

Object[] obj = new Object[] {answerIds};

//when
Map<String, List<Integer>> map = (Map<String, List<Integer>>) method.invoke(w, obj);

//than
assertThat(map).extracting("pass", String.class)
.contains(passWordList);
assertThat(map).extracting("fail", String.class)
.contains(failWordList);
}
  1. test할 private method가 존재하는 class를 직접 생성
  2. getDeclaredMethod()를 이용해서 해당 클래스에 존재하는 private method를 가져오고
  3. setAccessible()로 private method에 접근을 허용
  4. invoke()로 호출하는데 이 때 invoke()의 매개변수가 Object[] 이므로 원래 호출하려던 private method의 매개변수를 Object[]에 담은 후 Object[]을 매개변수로 넘겨줘야함

참고 사이트