20. 로그인/ 로그아웃 테스트
테스트 요점 정리
> 폼 서브밋 요청 (post)은 반드시 .with(csrf())를 추가할 것
> .andExpect(authenticated()) 또는 .andExpect(unauthenticated())로 인증 여부를 확인할 수 있다.
> 리다이렉트 응답은 .andExpect(status().is3xxRedirection())로 확인한다.
> 리다이렉트 URL은 .andExpect(redirectedUrl())로 확인할 수 있다.
> JUnit 5의 @BeforeEach와 @AfterEach
> 임의로 로그인된 사용자가 필요한 경우에는 @WithMockUser
테스트코드 작성
@SpringBootTest
@AutoConfigureMockMvc
class MainControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private AccountService accountService;
@Autowired
private AccountRepository accountRepository;
@BeforeEach
void init(){
SignUpForm signUpForm = new SignUpForm();
signUpForm.setNickname("jongwon");
signUpForm.setEmail("jong9712@naver.com");
signUpForm.setPassword("12341234");
accountService.processNewAccount(signUpForm);
}
// 회원정보가 중복으로 DB에 들어가니 삭제해줘야함
@AfterEach
void finish(){
accountRepository.deleteAll();
}
@DisplayName("이메일로 로그인 성공")
@Test
public void login_with_email() throws Exception{
// email이 아니라 nickname으로 인증하는 이유는
// AccountUser에서 nickname과 password 반환해주기 때문에 그 값으로 인증
mockMvc.perform(post("/login")
.param("username", "jong9712@naver.com")
.param("password", "12341234")
.with(csrf()))
.andExpect(status().is3xxRedirection()) // redirect 발생
.andExpect(redirectedUrl("/"))
.andExpect(authenticated().withUsername("jongwon"));
}
@DisplayName("닉네임으 로그인 성공")
@Test
public void login_with_nickname() throws Exception{
// email이 아니라 nickname 이유는
// AccountUser에서 nickname과 password 반환해주기 때문에 그 값으로 인증
mockMvc.perform(post("/login")
.param("username", "jongwon")
.param("password", "12341234")
.with(csrf()))
.andExpect(status().is3xxRedirection()) // redirect 발생
.andExpect(redirectedUrl("/"))
.andExpect(authenticated().withUsername("jongwon"));
}
@DisplayName("로그인 실패")
@Test
public void login_fail() throws Exception{
mockMvc.perform(post("/login")
.param("username", "1111")
.param("password", "00000000")
.with(csrf()))
.andExpect(status().is3xxRedirection()) // redirect 발생
.andExpect(redirectedUrl("/login?error"))
.andExpect(unauthenticated());
}
@WithMockUser // security.user에 있는 가짜정보 넣어줌
@DisplayName("로그아웃")
@Test
public void logout() throws Exception{
mockMvc.perform(post("/logout")
.with(csrf()))
.andExpect(status().is3xxRedirection()) // redirect 발생
.andExpect(redirectedUrl("/"))
.andExpect(unauthenticated());
}
}
로그아웃은 form servlet버튼으로 설정했다.
(server side쪽에서 구현할 필요 없음. spring security에서 알아서 처리해줌)
<!--spring security logout 핸들러가 처리-->
<form class="form-inline my-2 my-lg-0" action="#" th:action="@{/logout}" method="post">
<button class="dropdown-item" type="submit">로그아웃</button>
</form>
@WithMockUser
Security.user를 선언한 내용을 가져와서 임의의 인증된 유저정보를 생성해줌
인증된 유저가 있는 어떤 로직이 있는 테스트를 할 때 유용하게 사용됨
@Getter
public class UserAccount extends User {
// currentUser account와 일치
private Account account;
public UserAccount(Account account) {
super(account.getNickname(), account.getPassword(), List.of(new SimpleGrantedAuthority("ROLE_USER")));
this.account = account;
}
}
참고
'Dot Programming > Spring Clone' 카테고리의 다른 글
[스프링 웹앱 프로젝트 #21] 프로필 뷰 (0) | 2020.12.11 |
---|---|
[스프링 웹앱 프로젝트 #20] 로그인 기억하기 (0) | 2020.12.10 |
[스프링 웹앱 프로젝트 #18] 로그인 로그아웃 (0) | 2020.12.08 |
[스프링 웹앱 프로젝트 #17] 가입 확인 이메일 재전송 (0) | 2020.12.08 |
[스프링 웹앱 프로젝트 #16] 현재 인증된 사용자 정보 참조 (0) | 2020.12.07 |