Spring에서는 @SpringBootTest 어노테이션을 통해 통합 테스트를 진행할 수 있다. 하지만 @SpringBootTest 통합테스트는 어플리케이션 실제 구동하는 것 처럼 설정된 빈을 모두 로드하기 때문에 규모가 크면 시간이 오래걸린다.
- Slice Test는 Spring Boot에서 특정 계층을 테스트하는 방식이다.
- @SpringBootTest 처럼 어플리케이션 전체 컨텍스트를 로드하지 않고 필요한 빈들만 로드하여 기능들을 더 빠르고 집중적으로 테스트할 수 있다.
3-layer-architecture 구조의 Spring 어플리케이션에서 dto 테스트를 진행하고 Slice Test를 진행하면서 활용했던 어노테이션이나 메서드와 테스트 팁들을 정리해 보았다.
- 테스트를 진행하기 위해 필요한 정보들은 인터페이스를 따로 만들어서 테스트용 상수를 설정하고 해당 인터페이스를 implement해서 사용한다.
- 테스트 코드도 네이밍 컨벤션이 있다.
- DTO에 걸린 validation을 테스트하기 위해 Validation 패키지의 buildDefaultValidatorFactory() 메서드를 활용해서 Validator인터페이스의 validate 메서드를 구현하여 테스트 가능하다.
- asserJ 라이브러리의 assertion 메서드를 활용하면 더 풍부한 assertions를 작성할 수 있다.
- @ActiveProfiles 어노테이션으로 테스트 환경에서 어떤 프로파일을 활성화 할지 지정할 수 있다.
- @ActiveProfiles("test")으로 application-test.yml의 설정을 활성화시킬 수 있다.
- @WebMvcTest는 Slice Test를 수행하도록 하는 어노테이션 중에 하나로, spring mvc와 관련된 설정을 로드하여 해당 컨트롤러를 가볍게 테스트할 수 있다.
- @MockBean을 사용하여 Spring 빈을 Mock 객체로 대체할 수 있다
- 스프링프레임워크의 MockMvc로 컨트롤러에 REST API의 request가 controller에 적용되는지 테스트할 수 있다.
- MockMvc에 SecurityContext도 설정 가능하다.
- 부모 클래스에 setup 설정을 하면 좋다.
- perform 메서드로 실제 web 호출이 발생하는 것처럼 동작시킨다.
- mockito의 verify메서드로 어떤 메서드가 호출되었는지, 어떤 파라미터가 들어오는지 체크할 수 있다.
- mockito의 given().willReturn() 메서드를 통해, 테스트에서 특정 메서드가 실행됐을 때 설정값을 반환할 수 있다.
- 클래스를 따로 만들어서 테스트용 객체를 만드는 메서드를 만들어 사용하면 좋다.
- 테스트에서 ReflectionTestUtils.setField 메서드로 private 필드에 접근하여 값을 설정할 수 있다.
- 스프링프레임워크의 SerializationUtils.clone으로 객체를 deep copy할 수 있다.
- Spring MVC 테스트에서 JSON 응답을 검증하기 위해 JsonPath 표현식이 활용된다.
- @ExtendWith로 단위테스트에서 기능을 확장할 수 있다.
- SpringExtention.class로 확장하면 Spring Test Context와 통합할 수 있고, MockitoExtention.class를 쓰면 Mockito를 활용해 테스트를 진행할 수 있다.
- assertj에서 isEqualTo로 예상값과 비교할 때 주소값 기준으로 체크하면 객체를 비교할 수 없기 때문에, 어노테이션을 객체를 만들 때 @equalsandhashcode 적용시켜야 필드를 기준으로 같은 값인지 체크할 수 있다.
- repository를 테스트할 때 @DataJpaTest으로 jpa 설정값을 받아온다.
- @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 어노테이션으로 자동으로 설정된 데이터베이스를 사용하지 않고 직접 설정한 데이터베이스를 테스트용으로 사용할 수 있다.