본문 바로가기
개발/Java

[Java] 테스트가 어려운 코드

by devhooney 2023. 8. 23.
728x90

최범균님의 '테스트 주도 개발 시작하기'를 읽으면서 정리해본 글.

 

- 모든 코트를 테스트할 수 있는 것은 아님.

 

1. 하드코딩된 경로

- 예시

public void sync() throws IOException {
	
    Path path = Paths.get("D:\\data\\pay\\test.csv");
    
    ...(중략)...


}

 

위 코드에서 파일 경로가 하드코딩 되어 있다. 이 코드를 테스트하려면 해당 경로에 파일이 반드시 위치해야 한다. 만약 윈도우에 D드라이브가 없으면 테스트가 불가능하다. 또한, 윈도우 전용 파일 경로를 사용하고 있기 때문에 맥이나 리눅스로는 테스트가 불가능하다.

 

 

2. 의존 객체를 직접 생성

- 예시

// 의존 대상을 직접 생성
private PayInfoDao payInfoDao = new PayInfoDao();

public void sync() throws IOException {
	
	    
    ...(중략)...
	payInfos.forEach(pi -> payInfoDao.insert(pi));

}

 

위 코드를 테스트하려면 PayInfoDao가 올바르게 동작하는데 필요한 모든 환경을 구성해야한다. DB를 준비해야 하고 필요한 테이블도 만들어야 한다. 테스트를 실행하려면 데이터가 DB에 추가되므로 같은 테스트를 다시 실행하기 전에 기존에 들어간 데이터를 삭제해야 한다. 그렇지 않으면 중복 데이터로 인해 데이터 삽입에 실패하게 된다.

 

 

 

728x90

 

 

 

3. 정적 메서드 사용

- 예시

...(중략)...

public LoginResult login(String id, String pw) {

	int resp = 0;
    boolean authorized = AuthUtil.authorize(authKey)
	if (authorized) {
    	resp = AuthUtil.authenticate(id, pw);
    } else {
    	resp = -1;
    }
    
    ...(중략)...

}

 

위 코드는 AuthUtil 클래스의 정적 메서드를 사용하고 있는데, AuthUtil 클래스가 인증 서버와 통신하는 경우 이 코드를 테스트하려면 동작하고 있는 인증 서버가 필요하다. AuthUtil 클래스가 통신할 인증 서버 정보를 시스템 프로퍼티에서 가져온다면 시스템 프로퍼티도 테스트 환경에 맞게 설정해야 한다. 게다가 다양한 상황을 테스트하려면 인증 서버에 저장되어 있는 유효한 아이디와 암호를 사용해야 한다. 인증 서버 담당자가 휴가라도 가면 돌아올 때까지 기다려야 할 수도 있다.

 

 

4. 실행 시점에 따라 달라지는 결과

public int calculatePoint(User u) {

	Subscription s = subscriptionDao.selectByUser(u.getId());
    if (s == null) throw new NoSubscriptionException();
    Product p = productDao.selectById(s.getProductId());
    LocalDate now = LocalDate.now();
    int point = 0;
    if (s.isFinished(now)) {
    	point += p.getDefaultPoint();
    }
    ...(중략)...

}

calculatePoint() 메서드는 사용자의 구독 상태나 제품에 따라 계산한 결과 값을 리턴한다. 여기서 테스트를 어렵게 만드는 코드는 LocalDate이다. 같은 테스트 코드여도 LocalDate.now()에 따라 실행 결과가 달라진다. 어제까지 문제 없이 성공하던 테스트가 오늘은 깨질 수있다.

 

5. 역할이 섞여 있는 코드

6. 메서드 중간에 소켓 통신 코드가 포함되어 있는 경우

7. 콘솔에서 입력을 받거나 결과를 콘솔에 출력하는 경우

8. 테스트 대상이 사용하는 의존 대상 클래스나 메서드가 final인 경우

9. 테스트 대상의 소스를 소유하지 않아 수정이 어려운 경우

 

 

 

 

 

 

 

 

728x90