본문 바로가기

카테고리 없음

[Junit5] 테스트 코드 작성할때 헷갈리는 점 - 대역 기준 잡기

역시 책은 두번 봐야한다.

* 세번째 볼때는 또 다를 수 있음 주의 * 

첫번째 볼때는 대역을 만드는건 알겠는데 언제 어떤 기준을 잡고 대역을 만들어야 하는가에 대한 의문을 가지고 있었다. 

그 기준을 아래 내용을 통해 정리해 보았다. 

 

 

일단 대역은 왜 사용하는가? 

 

테스트를 작성하다보면 외부 요인이 필요한 시점이있다.

 

 - 테스트 대상에서 파일 시스템을 사용

 - 테스트 대상에서 DB로 부터 데이터를 조회하거나 데이터를 추가

 - 테스트 대상에서 외부의 HTTP 서버와 통신

 

이러한 외부 요인으로 테스트 결과가 다르게 나온다면? 그 테스트 코드는 100% 신뢰할수 없다. 

외부 API 를 사용할때 오늘 카드번호가 한달뒤에 만료된다면? 카드 유효성 로직에서는 결과가 정 반대로 나왔을것 이다.

이것또한 외부 요인으로 테스트 결과가 다르게 나온 안좋은 예라고 할수 있다. 

 

이렇게 테스트 대상에서 의존하는 요인때문에 테스트가 어려울때는 대역(test Double) 을 써서 테스트를 진행 할수 있다.  

대역의 종류에는  

스텁

구현을 단순한 것으로 대체한다. 테스트에 맞게 단순히 원하는 동작을 수행한다. 단순 Validator 같은 검증 클래스를 사용할수 있다. 

가짜

제품에는 적합하진 않지만 실제 동작하는 구현을 제공한다. DB 대신에 메모리를 이용해서 Repository 를 구현할수 있다.

스파이 

호출된 내역을 기록한다. 기록한 내용은 테스트 결과를 검증할때 사용한다. 

모의객체

기대한 대로 상호 작용하는지 행위를 검증한다. 기대한 대로 동작하지 않으면 익셉션을 발생 할수 있다. 

모의 객체는 스텁이자 스파이 이기도 한다.

 

 

그렇다면 어떻게 써야하는가? 

TC 입문자 입장에서 대역을 써서 외부 의존성 어쩌구, 알겠는데 대역을 도대체 언제 써야하는지 정확한 기준을 잡기가 어렵다. 어떻게 써야하는지 아래 예시를 보면서 확인해 보자. 

 

아래 클래스는 두가지를 담고있다.

 

UserRegister : 회원 가입에 대한 핵심 로직을 수행

WeakPasswordChecker : 암호가 약한지 검사한다.

 

또한 테스트의 목적은 UserRegister 에서 약한 암호일경우 Exception 을 수행시키는지를 확인 하는것이다. 

그리고 테스트 대상이 UserRegister 라면 WeakPasswordChecker 클래스는 약한 암호인지 여부를 알려주기만 한다.(로직 검증이 필요없다)

 

이 테스트 목적은 UserRegister 가 약한 암호인 경우와 그렇지 않은 경우에 대해 올바르게 동작하는지 확인 하는것이기 때문에 암호를 알려주는 WeakPasswordChecker 를 스텁으로 만들어 약한 암호인 경우 , 아닌경우를 필요에 따라 테스트에 반납할수 있도록 만들어 주기만 해도 될것이다. 또한 WeakPasswordChecker 는 외부 요인에 의존할수도 있기 때문에 암호여부만 확인할 경우에는 직접 가져올 필요 또한 없다. 

 

그렇다면 아래와 같이 스텁을 정할 수있다.

 

UserRegister : 회원 가입에 대한 핵심 로직을 수행

WeakPasswordChecker : 암호가 약한지 검사한다. (스텁 사용) 

 

- 이 외로 서비스 레이어에서 데이터 유효성 검증을 위한 테스트를 하는데, Service classRepository 인젝션된 상황에서 Repository 는 유효성 검증에 필요한 데이터만 가져오면 된다? 하면 Repository 를 대역으로 설정하여 검증에 필요한 의도한 데이터를 가져오도록 설정하면된다. 

 

뭐, 다른 기준이 있을수도 있다. 

반응형