Junit 테스트에서 인증된 사용자만 접근이 가능한 기능을 테스트해야 할 경우?
- 실제 DB에 저장되어 있는 정보에 대응하는 인증된 Authentication 필요
- 매번 인증 기능을 사용하기 위해서?
- UsernamePasswordAuthenticationToken 생성
- SecurityContextHolder.getContext().setAuthenticat(token)
- 번거로움..
어노테이션으로 간편하게 처리하는 방법
@WithAccount
@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithAccountSecurityContextFactory.class)
public @interface WithAccount {
String value();
}
WithAccountSecurityContextFactory
@RequiredArgsConstructor
public class WithAccountSecurityContextFactory implements WithSecurityContextFactory<WithAccount> {
private final AccountService accountService;
@Override
public SecurityContext createSecurityContext(WithAccount account) {
String nickname = account.value();
SignUpForm signUpForm = new SignUpForm();
signUpForm.setNickname("blupine");
signUpForm.setEmail("blupine@email.com");
signUpForm.setPassword("password");
accountService.processNewAccount(signUpForm);
UserDetails principal = accountService.loadUserByUsername(nickname);
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities());
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(authentication);
return context;
}
}
Test
@WithAccount("blupine")
@DisplayName("프로필 수정 폼")
@Test
void udpate_profile_form() throws Exception {
mockMvc.perform(get(SettingController.SETTINGS_PROFILE_URL))
.andExpect(status().isOk())
.andExpect(model().attributeExists("account"))
.andExpect(model().attributeExists("profile"));
}