JWT + Spring Security 환경의 Controller 테스트에 인증 정보 주입하기

문제

아래 Controller에 대한 테스트 코드를 작성하는 도중 인증 정보가 없어서 NPE가 발생하는 문제가 생겼다.

@PostMapping("/new")
public ResponseEntity<StudyGroupDto> studySave(@RequestBody @Valid RequestStudyGroupDto dto, @AuthenticationPrincipal CustomUserDetails user){
    StudyGroupDto studyGroupDto = studyService.createStudyGroup(dto, user.getId());
    return ResponseEntity.status(HttpStatus.CREATED).body(studyGroupDto);
}

 

해결

이전에 인증 과정을 통과하기 위해서 @WithMockUser라는 어노테이션을 사용한 적이 있다.

하지만 @WithMockUser는 단순히 인증을 통과하기 위한 것일 뿐, 인증 정보를 사용할 때는 값을 가지고 있지 않기 때문에 인증 정보를 활용할 수 없다.

이때 @WithUserDetails를 사용하면 인증 정보를 넣어줄 수 있다.

value에 username을 넣고, userDetailsServiceBeanName에 userDetailsService Bean을 등록해주면 된다.

setupBefore 속성은 인증 정보를 넣는 시점을 명시 할 수 있는데 default 값은 TestExecutionEvent.TEST_METHOD이다.

TEST_METHOD는 @Before 실행 전에 동작하고, TestExecutionEvent.TEST_EXECUTION은 @Before 이후에 실행되어 미리 생성해둔 유저 정보를 가져올 수 있다.

@WithUserDetails(value = "tester1", userDetailsServiceBeanName = "userDetailsService",
            setupBefore = TestExecutionEvent.TEST_EXECUTION)
@DisplayName("[POST] 스터디 생성 - 성공")
@Test
void create_study_success() throws Exception {
@BeforeTestMethod
    public void securitySetUp() {
        given(memberRepository.findByUsername(anyString()))
                .willReturn(Optional.of(
                                Member.builder()
                                        .id(1L)
                                        .username("tester1")
                                        .password("asdQWE123!@#")
                                        .name("홍길동")
                                        .birth(LocalDate.of(1999, 11, 23))
                                        .gender(Gender.M)
                                        .role(RoleType.ROLE_USER)
                                        .build()
                        )
                );
    }