UnitTesting 11 단위테스트 안티패턴
11 단위테스트 안티패턴
비공개 메서드 단위테스트
비공개 메서드는 테스트해서는 안된다
- 하나의 식별할수있는 동작만 테스트한다는 것을 위반한다.
- 테스트가 구현 세부사항과 결합되어 리팩터링내성이 떨어진다.
- private method에 중요한 도메인로직 등이 포함된 경우
- 비공개메서드가 너무 복잡하면 추상화가 누락된것, 별도 클래스로 도출해야할수도있다.
- private method -> public 으로 변환된 클래스.
- 비공개 메서드 테스트가 타당한 경우
- 코드 공개 여부와 목적의 관계
|..|식별할 수 있는 동작 |구현 세부사항|
|—|—|—|
|public|좋음|나쁨|
|private|해당 없음|좋음|
- 비공개 메서드가 구현 세부사항의 프록시에 해당하므로 비공개 메서드 테스트는 나쁜것, 테스트가 깨지기 쉬워진다.
- 예외
- ORM 사용을 위한 private constructor에 도메인 로직이 있는경우, 비공개이면서 식별가능한 동작이다.
- private 를 public으로 해도 테스트가 쉽게 깨지지않고, 오히려 캡슐화를 지키는데 필요한 전제조건이 public 생성자에 포함될수있어 좋을지도.
- 클래스의 public을 최소화 가 필요하다면, reflection을 사용해보자.
비공개 상태 노출
단위테스트 목적 만으로 비공개 상태를 노출하는것, 테스트는 특별한 권한이 따로 있어서는 안된다.
- 비공개로 지켜야하는 상태를 노출하지 않고 식별할수있는 동작만 테스트하라는 비공개 메서드 지침과 같다.
- 해당 상태를 사용하는 로직에서 간접적으로 테스트되어야한다.
테스트로 유출된 도메인 지식
- 테스트 내에서 결과를 계산하는 방식은 구현 세부사항과 결합된다.
- 구현 세부사항과 결합되어 리팩터링 내성이 0이다.
- 예상결과를 하드코딩하는것이 좋다. (ParameterizedTest 활용)
코드 오염
코드 오염 = 테스트에 필요한 제품 코드를 추가하는 것
- 유지비가 증가된다.
- 구체 클래스 대신 인터페이스로 추상화하고, 테스트용 구현체를 분리하자.
- 인터페이스는 잠재적인 버그에 대한 노출 영역을 늘리지 않는다.
구체 클래스를 목으로 처리하기
- 단일 책임 원칙을 위배하는 단점이 있다.
- 비관리 의존성을 통신하는 책임을 별도 클래스로 분리하여, 비관리 의존성만 목으로 사용하자.
시간 처리
- ambient context (anti)
- 제품코드를 오염시킨다.
- 정적 필드는 테스트간의 공유하는 의존성을 도입해 통합테스트 영역으로 전환되게 한다.
- 명시적 의존성으로서의 시간
- 시간을 제공하는 클래스를 서비스로 주입한다음, 나머지 연산에서는 값으로 전달 하여 테스트용 stub 인터페이스를 분리하자.