[트러블슈팅] 테스트에 실패했는데 왜 200..?

wannabeing·2025년 4월 26일
1

SPARTA-TIL

목록 보기
14/22

🔥 문제 상황

Controller

@PostMapping("/{menuId}")
public ResponseEntity<CommonResponseDto<OrderResponseDto>> sendOrder(
	@PathVariable(name = "menuId") Long menuId,
	@AuthenticationPrincipal UserAuth auth) {
	return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
		CommonResponseDto.of(
			OrderSuccessCode.ORDER_CREATE_SUCCESS,
			orderService.sendOrder(menuId, auth)
		)
	);
}

일부러 return할 때, ResponseEntity.status(BAD_REQUEST)로 설정해봤다.

Controller 테스트 코드

@WebMvcTest(OrderController.class)
@ActiveProfiles("test")
class OrderControllerTest {
	@Autowired
	MockMvc mockMvc;

	@MockitoBean
	OrderService orderService;

	@MockitoBean
	private JwtAuthenticationFilter jwtAuthenticationFilter;

	@DisplayName("새로운 주문을 요청(생성)합니다.")
	@Test
	@WithMockUser(username = "wannabeing")
	void sendOrder() throws Exception {
		// given
		...
        
       
		// when & then
		mockMvc.perform(MockMvcRequestBuilders
				.post("/api/orders/{menuId}", 1L)
				.contentType(MediaType.APPLICATION_JSON)
				.with(csrf()))
			.andDo(print())
			.andExpect(status().isCreated());
	}
 }
  • .with(csrf())는 Spring Security가 CSRF 보호를 사용하는 경우,
    테스트에 CSRF 토큰을 추가하기 위한 설정

🌀 왜 200뜸????

아니.. 성공해서 기분이 좋긴 하다만 BAD_REQUEST면 400이 떠야하는데..
무조건 200이 뜨는 상황이 발생해버렸다.. 어디가 문제였을까?

💡 문제는 의존성 주입!!

@WebMvcTest(OrderController.class)
@ActiveProfiles("test")
class OrderControllerTest {
	@Autowired
	MockMvc mockMvc;

	@MockitoBean
	OrderService orderService;

	// ✅ 이 부분이 문제였다!!!
	@MockitoBean
	private JwtAuthenticationFilter jwtAuthenticationFilter;
    ...

✅ 필터는 목(Mock)객체로 만들지 않아도 되는 부분이라고 한다.


💡 요청 처리 흐름

HTTP 요청 → Tomcat"Filter"DispatcherServletInterceptorController

❓ 왜 필터는 Mock 객체로 만들지 않아도 될까?

@Slf4j
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
	// ✅ 의존성 주입이 필요한 부분
	private final JwtTokenProvider jwtTokenProvider;
	private final BlackListService blackListService;
	
    ...
  • 필터는 DispatcherServlet 앞단에서 동작한다.
    테스트할 때는 스프링이 직접 필터 체인을 자동으로 구성해준다.
  • 그래서 필터는 "그냥 거쳐지거나" "필요 시 진짜 필터가 동작"한다.
    별도로 Filter를 Mocking할 필요가 없다.
  • 우리의 서비스의 경우, JwtFilter를 거치기 때문에
    필터가 필요한 의존성은 Mock으로 만들어주어야 한다.
  • 단, 필터가 의존하는 서비스 객체는 반드시 Mock 설정해야 한다!!
    ex. JwtTokenProvider, BlackListService
    이유: 이 객체들이 필터 내부 로직에서 실제 사용되기 때문.
  • 오히려 필터를 Mock으로 만들면,
    필터 내부의 중요한 인증/인가 로직이 아예 건너뛰어져 버려서
    실제 운영 로직과 테스트 코드가 따로 노는 문제가 생긴다.

근데 왜 400대가 안뜨는지는 아직까지도 몰?루...😇

@WebMvcTest(OrderController.class)
@ActiveProfiles("test")
class OrderControllerTest {
	@Autowired MockMvc mockMvc;
	@MockitoBean OrderService orderService;

	// ✅ 필터에게 필요한 의존성 주입
	@MockitoBean private JwtTokenProvider jwtTokenProvider;
	@MockitoBean private BlackListService blackListService;
    
    ...

따라서 필터를 Mock로 만들지 말고, 필터에 의존성인 두개의 서비스를 Mock으로 설정하였다.

야호~!~!~! 🚀🚀🚀🚀


내배캠 튜터님 (샤라웃 팀장님)

profile
wannabe---ing

2개의 댓글

comment-user-thumbnail
2025년 4월 28일

테스트 코드 너무 어렵습니다.. (샤라웃 지지합니다)

1개의 답글