[TIL][TDD] TDD 4편. 자바 Reflection 의 원리와 활용, Spring의 ReflectionTestUtils.invokeMethod
1. Reflection의 정의와 원리
자바의 Reflection은 어떤 클래스의 구현 내용을 모를 때, 해당 내용들을 조회할 수 있도록 자바에서 제공하는 API라고 한다.
이것은 참조 2에 따르면, 자바는 클래스 파일을 바이트 코드로 컴파일하여 static 영역에 위치하게 되므로 여기서 해당 클래스의 정보를 가져올 수 있는 것이라고 한다. 가져올 수 있는 정보는 아래와 같다.
ClassName
Class Modifiers
Package Info
Superclass
Implemented interfaces
Constructors
MethodsFields
Annotations
2. Reflection 사용해보기
TestClassForReflection라는 클래스를 임시로 만들고 .class 뒤에 .을 붙이면, intelliJ에서 여러 메서드를 제공한다. 이 메서드들이 바로 위에서 확인한 Reflection으로 가져올 수 있는 클래스의 정보들을 조회하는 메서드이다.

실제로 method를 조회해보면, TestClassForReflection 클래스에 작성해둔 getAgeForNextSomeYear 메서드와 Object에서 상속받아온 기본 메서드들이 조회되는 것을 확인할 수 있다.

TestClassForReflection.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Getter
@Setter
public class TestClassForReflection {
private String username;
public int getAgeForNextSomeYear(int age, int someYear) {
return age + someYear;
}
public TestClassForReflection(String username) {
this.username = username;
}
}
|
cs |
3. TDD에서 Reflection 활용하기
참조3. 에 따르면, 이 Reflection을 TDD에서 활용할 수 있다. 이전 TDD 3편 등의 글에서 Service layer에 작성된 private 메서드는 테스트코드에서 불러올 수 없으므로 따로 Service 클래스로 만들어서 단위 테스트를 진행할 수 있다고 했었다.
그러나, Reflection을 이용하면 이렇게 하지 않고 private 메서드를 마치 public 처럼 불러와서 테스트할 수 있다고 한다. Spring Framework의 ReflectionTestUtils.invokeMethod를 이용한다.
직접 사용해보니, 테스트가 되긴 된다(해당 클래스의 메서드를 private으로 변경 후 테스트).
다만, 아래 사진에서 체크 표시한 부분과 같이 메서드의 이름과 인자등을 직접 입력해주어야 하므로
(intelliJ가 다 알려줘서 그럴 일이 잘 없겠지만) Reflection으로 메서드 이름 및 인자들을 조회하여 인지한 상태로 사용해야할 것 같다.

참조
참조1. Minsub's Blog
https://gyrfalcon.tistory.com/entry/Java-Reflection
참조2. 개발자 지망생 브런치
참조3. DONGHWAN, KIM 님 블로그
https://yearnlune.github.io/java/java-private-method-test/#java-reflection