-
카테고리
-
세부 분야
백엔드
-
해결 여부
미해결
AccountControllerTest 실행오류
21.12.08 01:56 작성 조회수 659
0
안녕하세요.
알려주신대로 index 메서드의 두번째 파라미터에@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : account") Account account를 넣은 이후, AccountControllerTest를 돌렸을 때, 아래와 같은 오류가 나오고있는 상황입니다. @AuthenticationPrincipal UserAccount userAccount를 두번째 파라미터로 넣으면 잘 동작합니다.
@GetMapping("/")
public String index(Model model, @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : account") Account account) {
if ( account == null ) {
model.addAttribute("message", "Hello Spring Security");
} else {
model.addAttribute("message", "Hello, " + account.getUsername());
}
return "index";
}
오류 로그
Request processing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'account' cannot be found on object of type 'org.springframework.security.core.userdetails.User' - maybe not public or not valid?org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'account' cannot be found on object of type 'org.springframework.security.core.userdetails.User' - maybe not public or not valid?
이 경우, 테스트 코드를 바꿔줘야 할 부분이 있는건가요??
바쁘시겠지만 확인해주시면 감사하겠습니다.
답변을 작성해보세요.
1
백기선
지식공유자2021.12.09
Property or field 'account' cannot be found on object of type 'org.springframework.security.core.userdetails.User
이 에러를 보니까 아마도 UserDetailsService 구현체에서 User를 리턴하신것 같네요. User가 아니라 Account를 담고 있는 커스텀한 타입의 User를 리턴해야 할 것 같습니다. UserDetailsService 구현체 코드를 점검해 보셔야 할 것 같습니다.
nmnnhlba
질문자2021.12.11
이상하네요. 저도 그렇게 인지하고 loadByUsername 메서드에 아래와 같이 UserAccount 인스턴스를 리턴할 수 있도록 작성했는데요. 어디에서 막히는지 도무지 감을 못잡겠네요.
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Account account = accountRepository.findByUsername(username);
if ( account == null ) {
throw new UsernameNotFoundException(username);
}
return new UserAccount(account);
}
테스트가 막히는 부분은 @WithAnonymousUser, @WithUser, @WithMockUser(username = "admin", roles = "ADMIN") 애노테이션을 사용한 테스트에서 막힙니다.
당연히 통과되어야할 것 같은 테스트인데 어느 부분에서 막히는지 감조차 안오네요.
도저히 답을 찾을 수 없을 것 같아 코드를 압축하여 공유해드립니다. 확인해주시면 감사하겠습니다.
https://drive.google.com/file/d/1eRsEY7wXaMLfwVTdOoX-VwVrVoVQBCBl/view?usp=sharing
백기선
지식공유자2021.12.14
@WithMockUser등을 사용할 때 기본적으로 커스텀하게 작성한 UserDetailsService의 구현체를 쓰지 않고 내부적으로 mocking 한 UDS를 쓰기 때문에 그런 문제가 발생합니다. 레퍼런스를 보시면, 커스텀한 UDS를 사용해야 하는 경우에 @WithUserDetails를 쓰는 방법을 소개하고 있습니다.
https://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/test-method.html#test-method-withuserdetails
코드를 아래처럼 고치면 AccountSerivce를 사용해서 User를 찾으려고 하는것을 디버깅을 통해 알 수 있습니다. 다만, 문제는 이렇게 했을 때 해당 테스트에서 사용하는 유저 정인 admin이 없기 때문에 에러가 날 것입니다. 그 문제는 미리 해당 유저를 만든 다음에 테스트를 실행하도록 고쳐서 해결하실 수 있을겁니다.
@Test
@WithUserDetails(userDetailsServiceBeanName = "accountService")
@WithMockUser(username = "admin", roles = "ADMIN")
public void index_admin() throws Exception {
mockMvc.perform(get("/"))
.andDo(print())
.andExpect(status().isOk());
}
답변 1