• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

SpringSecurity 사용 시 Controller 테스트

24.02.25 15:34 작성 조회수 152

1

안녕하세요 좋은 강의를 제공해주셔서 너무 감사합니다. 평소 테스트에 대해 고민하던 많은 부분이 해결되었습다. 그러나 아직 해결하지 못 한 부분이 있습니다.

전 개인 프로젝트에 Spring Security 를 이용해 인증 및 인가를 구현하였습니다. 또한, 컨트롤러에 @AuthenticationPrincipal 을 이용해 인증 객체를 가져와 로그인한 회원의 정보를 사용하고 있습니다.

강사님의 경우 @WebMvcTest 를 이용해 컨트롤러만 띄워 최소한의 파라미터만 검증하였습니다. 저 역시 처음엔 @WebMvcTest 를 이용해 최소한의 비용으로 컨트롤러를 테스트해보려 했으나 테스트 수행 시 Security 관련 빈이 없어 잦은 오류가 발생하였습니다.

이 경우 @WebMvcTest 를 그대로 사용하며 TestSupport 와 같은 클래스에 시큐리티 관련 빈들을 모두 목킹하고 @AuthenticationPrincipal 으로 가져오는 인증객체 또한 목킹하는 것이 좋은 테스트일지
@SpringBootTest 를 사용한 다음 인증객체를 주입하는 것이 좋은 테스트인지 잘 판단이 안됩니다.
(@AuthenticationPrincipal 의 경우 컨트롤러 메서드의 파라미터로 들어가는데 이것 역시 목킹이 가능한지도 잘 감이 안잡힙니다.)

마지막으로 Spring Security 를 구성하는 필터 혹은 인터셉터나 kafka, websocket 같은 비동기 통신의 경우 실무에서 어떻게 테스트를 수행하는지 궁금합니다!

긴 질문 읽어주셔서 감사합니다

답변 2

·

답변을 작성해보세요.

1

안녕하세요, asdf 님!

Security와 관련한 WebMvcTest에 대해서는 @WithMockUser 키워드로 검색하시면 많은 자료가 나오는데요, 한번 학습해 보시면 좋을 듯 합니다. (아래 AI 인턴도 관련해서 자세한 답변을 이미 주었네요.)

kafka와 websocket에 대해서도 질문을 주셨는데, 기본적인 접근 방법은 강의에서 말씀드린 기조와 동일합니다.
내가 만든 시스템에 집중해서 테스트하고, 검증할 필요 없는 외부 시스템에 대해서는 mocking하여 최소한의 것만 검증합니다.
기본적으로 클래스 기준 단위 테스트를 작성할 수 있다면 그렇게 해보고, 더 유기적인 환경에서의 테스트가 필요하다면 스프링 서버를 띄워서 통합 테스트를 진행합니다.

감사합니다. 🙂

asdf님의 프로필

asdf

질문자

2024.03.05

답변 감사합니다ㅎㅎ

외부 시스템만 mocking 한다 가 중요한 포인트인거 같네요 감사합니다!

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.02.27

안녕하세요, 인프런 AI 인턴입니다.
Spring Security를 사용하여 인증과 인가를 테스트할 때는 @WithMockUser@WithMockCustomUser 같은 어노테이션을 사용하여 가짜 사용자 인증 정보를 목킹할 수 있습니다. @WebMvcTest를 사용하면 Spring MVC 관련 설정만 로드되기 때문에, 보안 설정이 필요한 테스트에서는 Spring Security 테스트를 지원하는 다른 설정이 필요합니다. 해당 클래스에서 컨트롤러 레이어만 띄우고 싶으시면 @WebMvcTest@MockBean을 조합하여 사용하면서, 필요한 보안 설정을 목킹하거나, @Import를 사용하여 필요한 보안 설정 클래스를 추가할 수 있습니다.

다음은 @WebMvcTest를 사용하여 스프링 시큐리티와 함께 MVC 컨트롤러를 테스트할 때, WithMockUser 어노테이션을 사용한 예시입니다:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(UserController.class)
class MySecurityTests {

@Autowired
private MockMvc mvc;

@Test
@WithMockUser(roles = "ADMIN")
void requestProtectedUrlWithUser() throws Exception {
    this.mvc.perform(get("/"));
}
}

@AuthenticationPrincipal을 목킹하는 것도 가능합니다. 테스트에서 인증 객체를 주입할 수 있는 방법으로 SecurityContextHolderAuthentication 객체를 설정하는 방법을 사용할 수 있습니다.

@SpringBootTest를 사용하는 것은 전체 애플리케이션 컨텍스트를 로드하기 때문에, 필요한 모든 빈이 생성되고, 실제와 가까운 환경에서 테스트를 진행할 수 있으나, 실행 속도가 느릴 수 있습니다. 따라서 상황에 따라 적절한 테스트 전략을 선택할 필요가 있습니다.

Spring Security 구성의 필터 또는 인터셉터, Kafka, WebSocket 등 비동기 통신을 사용하는 경우 실무에서는 종종 통합 테스트를 수행하여 실제 컴포넌트가 함께 작동하는지 확인합니다. 이를 위해 @SpringBootTest를 사용하여 실제 서버를 실행하는 테스트 환경을 구성할 수도 있습니다.

더 자세한 내용이 필요하시면 Spring Security의 테스트 문서를 참조하시면 도움이 될 것입니다.

관련된 Spring Boot 문서의 원본 URL은 다음과 같습니다:
- Spring Security 테스트 문서
- Spring MVC 테스트 자동 구성 문서

복잡한 질문에 대해 깊이 있게 생각해보고 계셔서 오히려 저희 측이 감사드립니다, asdf님.

asdf님의 프로필

asdf

질문자

2024.03.05

늦게 확인했네요 답변 감사합니다ㅠㅠ

답변해주신 키워드 기반으로 더 공부해보겠습니다!