😰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());
}
😎위와 같이 하면 테스트가 잘 통과하는 것을 확인할 수 있습니다.