문제점
@Import(HttpEncodingAutoConfiguration.class)
@ExtendWith(RestDocumentationExtension.class)
public abstract class RestDocsSupport {
protected MockMvc mockMvc;
protected ObjectMapper objectMapper = new ObjectMapper();
@BeforeEach
void setUp(RestDocumentationContextProvider provider) {
this.mockMvc = MockMvcBuilders.standaloneSetup(initController())
.addFilters(new CharacterEncodingFilter("UTF-8", true))
.apply(documentationConfiguration(provider))
.build();
}
protected abstract Object initController();
}
- 기존에 Rest docs 테스트를 진행할 때는 여기 초기 설정으로 회원 인증 없는 테스트를 진행했습니다
- @AuthenticationPrincipal이라는 어노테이션을 사용했던 Controller가 없었습니다.
- 이 설정을 그대로 가지고와서 BoardController를 테스트할 때..
@PostMapping("")
public ResponseEntity<Void> createBoard(
@RequestBody @Valid PostCreateRequestDto requestDto,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
boardService.create(requestDto, userDetails.getUsername());
return ResponseEntity.ok().build();
}
java.lang.NullPointerException: Cannot invoke "com.zoo.boardback.domain.user.entity.User.getEmail()" because the return value of "com.zoo.boardback.domain.auth.details.CustomUserDetails.getUser()" is null
디버깅을 해봤습니다..
네 당연히 NULL값이여야 합니다.
해결책
서버가 안 띄워졌으므로 당연히 주입이 안 되는게 맞았습니다. (찾는데 2시간..)
아마도 ArgumentResolver 자체가 동작이 안 되겠죠..
@Import(HttpEncodingAutoConfiguration.class)
@WebMvcTest({
BoardController.class
})
@ExtendWith({RestDocumentationExtension.class})
public abstract class RestDocsSecuritySupport {
protected MockMvc mockMvc;
protected ObjectMapper objectMapper = new ObjectMapper();
@MockBean
protected BoardService boardService;
@MockBean
protected FavoriteService favoriteService;
@BeforeEach
void setUp(WebApplicationContext webApplicationContext
,RestDocumentationContextProvider provider) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(provider))
.build();
}
}
- 새로운 추상 클래스를 만들었습니다.
- 일단 @WebMvcTest를 붙여주어 서버가 띄워주기 때문에 정상적으로 SecurityContext에 주입이 된걸 확인할 수 있습니다.
- @MockBean으로 BoardController에 필요한 생성자 클래스들을 주입해주면 끝~ 입니다.
느낀점
- 스프링 시큐리티라는 스프링에 종속된 기술을 사용하면서, 단위테스트를 하려고 했던 부분 반성합니다.!