java.lang.AssertionError: Status expected:<200> but was:<403>
Expected :200
Actual :403
@WebMvcTest(MemberController.class)
class MemberControllerTest {
@MockBean
private MemberService memberService;
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
void duplicate() throws Exception {
// given
String url = "/api/duplicate/email";
// when
DuplicateRequestDto duplicateRequestDto = new DuplicateRequestDto(email, null);
mockMvc.perform(MockMvcRequestBuilders.post(url)
.content(objectMapper.writeValueAsString(duplicateRequestDto))
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk());
// then
}
}
mockMvc.perform 요청 시 403 에러가 나오는 에러 발생
Spring Security에서 제공하는 CSRF (Cross-Site Request Forgery) 보호 때문에 POST 요청에 대해 CSRF 토큰이 필요하다.
@WebMvcTest(MemberController.class)
@AutoConfigureMockMvc(addFilters = false)
class MemberControllerTest {
}
이렇게 @AutoConfigureMockMvc(addFilters = false) 추가하여 Spring Security의 자동 구성을 비활성화하고 모든 요청을 허용하도록 설정할 수 있다. 하지만 이 설정은 모든 필터를 추가하지 않는 것이기 때문에 인증된 유저를 테스트할 때 무의미할 것 같아서 다른 방법을 좀 더 찾아보았다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.and()
.authorizeRequests()
.anyRequest().permitAll()
나는 Rest API를 만들고 있고 JWT를 이용해 Access Token을 생성하였기 때문에 http.csrf().disable() 추가가 되어있었지만 403 에러가 여전히 발생하였다. 또한 permitAll()로 모든 접근을 허용하였음에도 불구하고 403 에러가 발생하였다.
@Test
@WithMockUser
void duplicate() throws Exception {
// given
String url = "/api/duplicate/email";
// when
DuplicateRequestDto duplicateRequestDto = new DuplicateRequestDto(email, null);
mockMvc.perform(MockMvcRequestBuilders.post(url)
.content(objectMapper.writeValueAsString(duplicateRequestDto))
.contentType(MediaType.APPLICATION_JSON)
.with(csrf()))
.andExpect(status().isOk());
}
인증된 유저를 추가하고 csrf 토큰을 코드에 추가해주어 status 200 이 나오도록 해결하였다.