본문 바로가기
✅ 테스트

private 메서드도 테스트를 해야 할까? (private 메서드 테스트 하고 싶을 때...) ✅ 👃

by kukim 2022. 2. 16.

해당 글은 페이스북 그룹 javawocky 박성철 님의 글을 시작으로 하단 Reference을 참고하여 요약했습니다.

자세한 내용은 링크를 참고해주세요


public 메서드의 테스트를 작성하다 보면 private 메서드도 테스트하고 싶은 마음이 들 때가 있다. public 메서드 테스트가 충분하지 않아 보인다. 테스트가 적거나 불안해 보인다. 하지만 보통 public 메서드를 테스트한다면 연결(종속)된 private 메서드도 이미 테스트했다고 생각한다. 그렇다면 public 메서드만 테스트하면 될까? private 메서드도 테스트를 해야 할까?

정답은 없다. 현재 프로그래밍하는 시점의 context을 고려하자.

 

그렇다. 정답은 없다.

그래도 3가지 상황을 통해 private 메서드의 테스트 여부를 알아보자.


먼저 보는 요약

public 메서드 테스트 만으로 충분하다 -> private 메서드 테스트하지 말자.(case 1)

그래도 private 메서드를 테스트해야겠다는 생각이 든다면

- 설계를 되돌아보고 조치하자 -> 설계가 잘못되었다. (case 2)

- 정말 어쩔 수 없이.. private 메서드 자체를 테스트 하자 ->  private 메서드 테스트하는 방법(case 3)

 

예제

예제는 Statistics 클래스에 public mean() 메서드가 있고 private sum() 메서드가 있다. mean() 안에 sum()이 포함되어 있다. (이해를 돕기 위한 아주 단편적인 예 링크 3 참고)

public class Statistics{
	public double mean(double[] data){
		return sum(data)/data.length;
	}


	private double sum(double[] data){
		...
	}
}

 

✅  Case 1 : private 메서드의 범위와 영향력

상황 1

1. 현재 프로젝트 초반이다. 아직 다른 곳에서 sum()을 사용하지 않고 다른 클래스에서도 동일한 역할을 하는 중복된 코드가 없다. sum()은 유일하게 mean()에서만 사용하고 있다.

2. mean 메서드에 sum이 모두 포함되어있고 강한 의존 관계를 갖는다.

 

이때 public mean() 메서드 테스트 만으로 private sum() 메서드를 커버 하기 때문에 충분해보인다. -> private 메서드 테스트 안해도 된다.

 

Case 2 : 설계를 점검하자.

상황 2

1. 프로젝트가 커지면서 같은 클래스 내에 sum() 메서드를 참조하고 있는 곳이 점점 많아졌다.

2. sum() 메서드가 불안하다. 테스트하고 싶은 욕구가 커졌다.

 

private 메서드를 테스트해야 할 필요성을 느낀다면 bad smell👃 일 수 있다. 설계를 점검하자.

이 시점에서 sum 메서드를 public으로 바꾸거나 아예 객체로 분리하는 설계가 필요할 수 있다.

설계를 바꾼 후 sum에 대해 테스트를 할 수 있다.

 

✅ Case 3 : 그냥 private 메서드를 강제로 테스트해버리자

상황 3

아무리 고민해도 private 메서드 테스트가 꼭 필요해 보인다. 하지만 객체 분리가 어렵거나 반드시 private 상태여야 한다. 강제적으로 테스트하자.

 

- 방법 1 : 테스트하고 싶은 메서드의 접근 제어자 범위(package-private, protected)를 바꾸어 테스트한다.

- 방법 2: 자바의 리플렉션을 활용하여 강제적으로 private메서드를 호출한다. 

    - 2.1. PowerMock의 Whitebox.invokeMethod

    - 2.2. Junit Addons의 PrivateAccessor 

    - 2.3. 직접 리플렉션 사용

 

📄 보통 어떤 private 메서드를 테스트해야 할까?

- 설계가 잘못된 경우

- private 메서드가 많은 곳에 결합되어 있는 경우

- non determinisitc(비결정적인) 로직 (e.g. 시간, 랜덤수)

- 외부 리소스 의존 로직 (e.g. 데이터 베이스, 파일 시스템)

- 시간이 많이 걸리는 로직

- +a

 

마치며

private 메서드의 테스트 여부는 정답이 없다.
현재 프로그래밍하는 시점의 context을 고려하자.

보통, private 테스트하지 말자. 만약 해야하는 상황이라면 현재 코드 설계가 잘못되었는지 되돌아보자. 그래도 해야겠다면 private test를..

 

Shoud I Test Private Mehods? 


⛓ Reference

링크 1: javawocky 박성철 : 테스트 코드를 작성하실 때 private 메서드도 테스트하시나요?

링크 2 : Don’t Test Private Methods

링크 3 : 테스트 상태인 Private 메서드를 Public메서드로 변환 시 Unit Testing은 어떻게 해야 하나? (Jin-Wook Chung, 박재성 님 등의 토론)

링크 4 : private 메서드를 어떻게 테스트해야 할까요?

링크 5 : 리플렉션을 활용한 private 메서드 테스트 - PowerMock의 Whitebox.invokeMethod

링크 6: 리플렉션을 활용한 private 메서드 테스트 - Junit Addons의 PrivateAccessor 

대표 이미지 : Glenn Carstens-Peters

댓글