spring security @WithUserDetails

greenTea·2023년 5월 30일
0

문제 발생 코드

😰spring security가 잘 적용되었는지 @WithUSerDetails를 걸어 테스트를 해보았는데 문제가 발생하였습니다.

먼저 해당 코드를 보면 아래와 같습니다.

@Transactional
@AutoConfigureMockMvc
@SpringBootTest
class MyControllerTest {

    @Autowired
    MemberRepository memberRepository;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    MockMvc mvc;

    @BeforeEach
    void setUp() {
        Member member = Member.builder()
                .username("user")
                .email("user@naver.com")
                .password(passwordEncoder.encode("1111"))
                .build();
        member.addRole(Role.USER);
        Member save = memberRepository.save(member);
    }

    @WithUserDetails(value = "user")
    @DisplayName("USER권한 접속 테스트")
    @Test
    void t1() throws Exception {
        mvc.perform(get("/member"))
                .andExpect(MockMvcResultMatchers.handler().methodName("member"))
                .andExpect(MockMvcResultMatchers.handler().handlerType(MyController.class))
                .andExpect(status().is2xxSuccessful());
    }

}

간단하게 테스트만 통과시키기 위해 member객체를 저장하고 해당 member의 이름을 이용하여 로그인을 시켜서 접속이 가능한지를 보는 테스트입니다.

2.에러 발생

위 코드를 진행해보면 아래와 같은 에러가 발생합니다.

java.lang.IllegalStateException: Unable to create SecurityContext using@org.springframework.security.test.context.support.WithUserDetails(setupBefore=TEST_METHOD, userDetailsServiceBeanName="", value="user")

😭해당 에러가 발생한 이유는 간단합니다. user라는 member를 찾을 수 없기 때문입니다. @WithUserDetails를 사용하게 되면 @Before Each를 실행하기전에 먼저 @WithUserDetails를 통해 로그인을 시도하게 되는데 아직 저장이 되지 않았기에 테스트에 실패하게 된 것입니다.

해결 방법

🧐위 문제를 해결하는 방법에는 다양한 방법이 있지만 여기서는 @WithUserDetails를 늦게 실행하도록 하겠습니다.
늦게 실행하게 하려면 @WithUserDetails에 setupBefore =TestExecutionEvent.TEST_EXECUTION를 적용하면 됩니다.

    @WithUserDetails(value = "yohan",
    setupBefore = TestExecutionEvent.TEST_EXECUTION)
    @DisplayName("USER권한 접속 테스트")
    @Test
    void t1() throws Exception {
        mvc.perform(get("/member"))
                .andExpect(MockMvcResultMatchers.handler().methodName("member"))
                .andExpect(MockMvcResultMatchers.handler().handlerType(MyController.class))
                .andExpect(status().is2xxSuccessful());
    }

😎위와 같이 하면 테스트가 잘 통과하는 것을 확인할 수 있습니다.

profile
greenTea입니다.

0개의 댓글