😰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의 이름을 이용하여 로그인을 시켜서 접속이 가능한지를 보는 테스트입니다.
위 코드를 진행해보면 아래와 같은 에러가 발생합니다.
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());
    }
😎위와 같이 하면 테스트가 잘 통과하는 것을 확인할 수 있습니다.