본 글은 우아한 테크코스 프리코스 1주차 미션 중 공부한 내용을 기록한 것이다.
-> 우아한 테크코스 프리코스 1주차 미션 java-onboarding
-> 필자가 제출한 코드
-> 1주차 미션 회고
private 메소드 테스트
- 문제를 해결하며 private으로 설정된 변수, 메소드 관련 테스트에 대해 고민이 있었다.
- 관련해서 알아보니, private으로 선언된 변수 혹은 메소드에 대해서는 테스트를 진행하지 않는 것이 권장되었다.
- 하지만 테스트 해 볼 수 있는 방법에 대해서는 알고 있어야 할 것 같아 알아보았다.
<private 변수, 메소드에 접근하기>
- REFLECTION을 활용해 private 메소드 혹은 필드에 접근하여 접근 가능 여부(Accessible)를 설정할 수 있다.
(private 메소드의 Accessible 설정)
Method calcNumberOfBillsMethod = BillConverter.class
.getDeclaredMethod("calculateNumberOfBills", UnitsOfBill.class, int.class);
calcNumberOfBillsMethod.setAccessible(true);
(private 변수의 Accessible 설정)
Field numberOfBillsField = BillConverter.class.getDeclaredField("numberOfBills");
numberOfBillsField.setAccessible(true);
- 위와 같이 BillConverter 클래스 내부에 특정 메소드 혹은 필드에 접근하여 Method, Field 객체를 생성할 수 있다.
- 이렇게 생성된 Method, Field 객체를 통해 접근 가능 여부를 수정할 수 있다.
- Accessible을 true로 설정한 후, 다음과 같이 메소드를 호출하거나, 필드 값을 받아올 수 있다.
(private Method 호출)
BillConverter billConverter = new BillConverter();
int money = 32_345;
Object change = calcNumberOfBillsMethod
.invoke(billConverter, UnitsOfBill.valueOf("TEN_THOUSAND", money));
- invoke(메소드 수행할 객체 이름, 해당 메소드의 파라미터)
- billConverter 객체 내에서 함수가 수행된다.
(private Field 접근)
Object numberOfBills = numberOfBillsField.get(billConverter);
- get(필드 값 가져올 객체 이름)
- billConverter의 멤버 변수 numberOfBills를 가져온다.
- private으로 설정된 메소드 혹은 Field 정보를 가져와 Method, Field 객체 생성한다.
- 생성된 객체를 통해 Accessible을 true로 수정한다.
- 테스트 할 클래스의 객체(billConverter)를 생성하고, Accessible을 수정한 Method와 Field 객체에 적용한다.
<private 메소드에 대한 테스트가 권장되지 않는 이유>
- 애초에 private은 클래스 내부에서만 동작되어야 하며, public으로 설정된 다른 멤버 메소드에 의해 호출된다.
- 즉, 굳이 private 메소드에 대해 테스트를 진행하지 않아도, public으로 설정된 메소드만으로도 충분히 테스트가 가능하다.
- 또한 private 메소드는 외부에서 접근할 수 없도록 설정되어 클라이언트와의 결합도를 낮추는 역할도 갖는다.
- 하지만 클라이언트에 해당하는 테스트가 내부 메소드에 대해 알 수 있게 되는 것은 결합도를 높일 수 있다.
- 이는 유지 보수 과정에서 테스트에 대한 비용을 증가시키는 요인이 될 수 있다.