Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Java
- 기본유형
- 코딩테스트
- 완전탐색
- DFS
- 코딩테스트실력진단
- Spring
- 다익스트라
- SSAFY
- 알고리즘
- 그래프
- database
- SWEA
- 트러블슈팅
- BFS
- 부분수열의합2
- 유니온파인드
- 싸피
- Union Find
- 백준
- 코드트리
- 그리디
- 완탐
- 자바
- 알고리즘기본개념
- DP
- JUnit
- JPA
- 코테
- 다시보기
Archives
- Today
- Total
HwangHub
[디버깅] webMvcTest 수행시 401 Unauthorized 에러 본문
Paging 조회 API 테스트코드를 아래와 같이 작성하였고, security filterchain에서는 모든 요청에 대하여 열어두었다.
@WebMvcTest(controllers = PostController.class)
@ActiveProfiles("test")
class PostControllerTest {
@Autowired
private ObjectMapper om;
@Autowired
private MockMvc mockMvc;
@MockBean
private PostService postService;
@MockBean
private PostRepository postRepository;
@DisplayName("유저가 입력한 키워드, 그리고 클라이언트에서 전해주는 page=0++, size=8으로 게시글을 검색/조회한다.")
@Test
void searchPost() throws Exception {
// given
String keyword = "키워드";
String page = "0";
String size = "8";
MultiValueMap<String, String> info = new LinkedMultiValueMap<>();
info.add("keyword", keyword);
info.add("page", page);
info.add("size", size);
// then
mockMvc.perform(get("http://localhost:8080/api/v1/entities")
.header("accept", "application/json")
.params(info)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(print());
}
}
수행 결과는 실패였다.
적잖이 당황했다. 분명 filterchain에서는 permitAll()을 먹여뒀는데 401이 뜨는 것이 의아했다. 반면에 swagger에서는 또 200이 잘 떴다.
아무래도 내부적으로 내가 정확하게 알지 못하는 로직에 의해 필터링에 걸리는 듯 했다.
가정하기로는, webmvctest 로직이 일부 bean만 관리하므로 생기는 문제라고 추측하였다. 즉, webMvcTest 테스트 코드 입장에서는 securityConfig bean의 내용은 모르지만, security가 있으니 당연히 인증 프로세스를 거친다고 가정하는 것으로 보였다.
따라서 해당 부분을 알아본 결과, 다음과 같은 내용을 얻을 수 있었다.
- security가 의존성으로 추가되면 기본적으로 모든 요청에 대하여 인증 절차를 거치는 것으로 기본 적용되어있기 때문에 webMvcTest 수행시에 security filter에 걸릴 수 있다.
- 나는 코드 상에서 header에 인증 토큰을 추가해주지 않았기 때문에 401이 뜨게 된다.
- 따라서 요청을 할 때 권한 정보를 같이 넘겨줘야 하는데, 로그인이 잘 되는지를 검증하는 test가 아니므로 이를 매번 추가해주는 것은 불필요하다. 따라서 이러한 "인증된 사용자" 또한 mock 객체로 사용할 수 있도록 @WithMockUser 라는 어노테이션을 지원해준다.
- @WithMockUser - 인증된 사용자
- @WithAnonymousUser - 미인증 사용자
- @WithUserDetails - 메서드가 principal 내부의 값을 직접 사용하는 경우에 사용 (별도 사전 설정 필요)
- security test시 403오류가 발생할 수도 있으며, 이는 csrf때문에 발생한다.
- Test코드에서도 csrf의 주소 값을 Http 요청할때 넣어 같이 보내줘야 하므로 .with(csrf( ))을 통해 담아준다.
솔루션 :
@WithMockUser 추가
@DisplayName("유저가 입력한 키워드, 그리고 클라이언트에서 전해주는 page=0++, size=8으로 게시글을 검색/조회한다.")
@Test
@WithMockUser
void searchPost() throws Exception {
// given
String keyword = "키워드";
String page = "0";
String size = "8";
MultiValueMap<String, String> info = new LinkedMultiValueMap<>();
info.add("keyword", keyword);
info.add("page", page);
info.add("size", size);
// then
mockMvc.perform(get("http://localhost:8080/api/v1/entities")
.header("accept", "application/json")
// .params(info)
.param("keyword", keyword)
.param("page", page)
.param("size", size)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(print());
}
출처:
참고(WebMvcTest 어노테이션):
'무엇을 합니다 > 프로젝트' 카테고리의 다른 글
[리팩토링] post 엔티티 body 필드 TEXT 적용 (0) | 2023.10.13 |
---|---|
[리팩토링] dto를 더욱 적극적으로 사용 (1) | 2023.10.13 |
[리팩토링] AuthenticatedUserUtils 사용하여 로그인 유저 Id를 추출 (0) | 2023.10.13 |
[리팩토링] 레거시 조회 API 성능 최적화 15000ms -> 180ms (0) | 2023.09.10 |
[고민] 유저가 작성한 게시글 조회는 누구의 관심사인가 (0) | 2023.07.24 |
Comments