Controller Test에서 Interceptor로 인한 문제와 해결 방법

김이·2024년 12월 19일

문제 상황

Spring Boot 애플리케이션에서 @WebMvcTest를 사용해 Controller 를 테스트하던 중, 필터나 인터셉터로 인해 테스트가 실패하는 상황이 발생했습니다.

코드 중 일부 :

    @Test
    void searchAll() throws Exception {
        List<ReservationResponseDto> reservations = List.of(
                new ReservationResponseDto(
                        1L,
                        "user1",
                        "item1",
                        LocalDateTime.of(2024, 12, 20, 10, 0),
                        LocalDateTime.of(2024, 12, 20, 12, 0)
                )
        );

        Mockito.when(reservationService.searchAndConvertReservations(Mockito.anyLong(), Mockito.anyLong())).thenReturn(reservations);

        ResultActions result = mockMvc.perform(get("/reservations/search")
                .param("userId", "1")
                .param("itemId", "1"));

        result.andExpect(status().isOk());
    }

위 코드가 실행 했을때 , "세션이 끊어졌습니다" 라는 메세지를 발견했습니다.

원인 분석

Interceptor의 영향 : 생각해보니 인터셉터 문제일거같다. 라는 생각이 들어서 인터셉터를 확인해봤습니다.

UserRoleInterceptor 클래스에서 문제가 있었던걸 발견했습니다.

간단한 테스트를 위해서 인터셉터를 비활성화 하고싶어, 방법을 찾아봤습니다.

해결 방법

@AutoConfigureMockMvc(addFilters = false) // 필터 비활성화

위 어노테이션을 클래스단에 설정해주면 될거같았습니다.

하지만 똑같은 에러가 계속 발생했습니다.

인터셉터가 계속 동작한다고 생각이 들어, Mock객체로 만들어서 실제로 동작하지 않게 하면 되겠다! 라는 생각으로 아래 코드를 작성해봤습니다.

@MockitoBean
UserRoleInterceptor userRoleInterceptor;

코드 삽입 후

드디어 테스트가 성공했습니다!

위 테스트의 목적은 Controller의 동작에 목적이 있는 테스트여서 가능한 방법이고, 통합테스트 혹은 권한을 테스트하기 위해서는 당연히 위 방법을 사용하면 안됩니다!

정리 및 배운 점

1.	Interceptor와 Controller 테스트의 분리
•	Interceptor의 동작과 Controller의 동작은 독립적으로 테스트하는 것이 좋습니다.

2.	Mock으로 의존성 우회
•	Mockito를 활용하면 테스트 환경에서 필요없는 외부 의존성을 제거할 수 있습니다.

3.	테스트 환경 구성의 중요성
•	테스트 시 필요하지 않은 요소(필터, Interceptor 등)를 처리하지 않으면
의도치 않은 결과를 초래할 수 있습니다.
profile
공부!

0개의 댓글