MockMvc를 이용해 Security Filter 테스트를 진행하기 위해, MockMvc 자체에 Filter를 추가하는 방식을 채택했었다.
테스트 코드를 작성하는 중 결과에서 ???.???
형식으로 결과 출력이 제대로 되지 않는 현상이 있었다.
2가지 방법을 찾았는데, 실제로 2가지 중에 1가지만 적용해도 해결될 때가 있고, 2가지 다 적용해야 해결될 때도 있는 등의 문제가 있어 조금 더 찾아봐야 할 것 같지만, 일단 올려두겠다.
1. mvc에 EncodingFilter를 추가 / 변경
Security Filter를 추가하는 방법은 생략한다.
다음과 같이 인증 실패와 관련한 테스트를 진행하는 상황이다.
참고로, WebApplicationContext는 DispatcherServlet이 직접 사용하는 Controller를 포함한 웹 관련 빈을 등록하는 데 사용한다.
.addFilters()
는 Filter를 등록하는 과정이다.
JwtTokenExceptionFilter
, JwtTokenFilter
,
UsernamePasswordAuthenticationFilter
는 해당 테스트에 필요한 Security Filter 들이다.
Filter를 등록하듯이, 다음과 같은 인코딩 필터도 추가해준다.
.addFilters(new CharacterEncodingFilter("UTF-8", true))
@WebMvcTest(PostApiController.class)
class PostApiControllerTest {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@Autowired
WebApplicationContext context;
@Test
@DisplayName("포스트 작성 실패(1) - 인증 실패 (Bearer 토큰으로 보내지 않은 경우)")
public void post_create_fail1() throws Exception {
String token = JwtTokenUtil.createToken("user", "secretKey", 1000 * 60 * 60L);
mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(new CharacterEncodingFilter("UTF-8", true)) // 한글 깨짐 방지 필터
.addFilters(new JwtTokenExceptionFilter())
.addFilters(new JwtTokenFilter("secretKey"))
.addFilters(new UsernamePasswordAuthenticationFilter())
.apply(springSecurity())
.build();
mockMvc.perform(post("/api/v1/posts")
.with(csrf())
.header(HttpHeaders.AUTHORIZATION,"Basic " + token) // Basic으로 보냄
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(postCreateRequest)))
.andExpect(status().is(INVALID_TOKEN.getStatus().value()))
.andDo(print());
}
}
2. application.yml에 설정 추가
server:
servlet:
encoding:
force-response: true
Leave a comment