과정을 즐기자

테스트 코드 작성시 로그인 인증이 필요할 때 본문

Spring

테스트 코드 작성시 로그인 인증이 필요할 때

320Hwany 2023. 1. 16. 17:06

웹툰 서비스를 만드는 프로젝트를 진행하면서 테스트 코드 작성시 로그인 인증이 필요한 경우가 생겼다. 

우선 배경부터 설명하자면 일반 회원이 아닌 작가로 로그인 한 경우에만 만화를 등록할 수 있다.

이때  @LoginForAuthor을 만들었고 ArgumentResolver로 로그인 한 작가인지를 확인하였다.  

 

CartoonController

@RequiredArgsConstructor
@RestController
public class CartoonController {

    private final CartoonService cartoonService;

    @PostMapping("/cartoon")
    public ResponseEntity<Void> save(@LoginForAuthor AuthorSession authorSession,
                                     @RequestBody @Valid CartoonSave cartoonSave) {
        cartoonService.save(cartoonSave, authorSession);
        return ResponseEntity.ok().build();
    }
}

마주친 문제

만화를 등록하려면 우선 작가로 로그인을 해야한다. 만화 등록 테스트 코드를 작성하려면 먼저 

작가로 로그인한 회원인지부터 확인해야한다. 테스트 케이스에서 어떻게 로그인한 작가인지를 

알려줄 수 있는 지를 고민하게되었다.  

 

해결 과정

MockMvc를 이용하여 HttpServletRequest를 반환받을 수 있다는 사실을 알게되었다. 

MockMvc로 로그인 과정을 진행한 후 HttpServletRequest로 HttpSession을 반환 받은 후 

MockHttpSession를 만들어 이것을 이용하였다.  

 

CartoonControllerTest는 ControllerTest를 상속받는다. ControllerTest에 다음과 같이 

회원가입 메소드와 위에서 말한 MockMvc를 이용한 로그인 메소드를 만들었다.  

 

ControllerTest

protected Author saveAuthorInRepository() {
    Author author = Author.builder()
            .nickName("작가 이름")
            .email("yhwjd99@gmail.com")
            .password("1234")
            .build();

    authorRepository.save(author);
    return author;
}

protected MockHttpSession loginAuthorSession() throws Exception {
    AuthorLogin authorLogin = AuthorLogin.builder()
            .email("yhwjd99@gmail.com")
            .password("1234")
            .build();

    String loginJson = objectMapper.writeValueAsString(authorLogin);

    MockHttpServletRequest request = mockMvc.perform(post("/author/login")
                    .contentType(APPLICATION_JSON)
                    .content(loginJson))
            .andReturn().getRequest();

    HttpSession session = request.getSession();
    return (MockHttpSession)session;
}

 

CartoonControllerTest

이렇게 만든 두 메소드를 이용하여 만화를 등록하는 테스트 코드를 작성하자. 

메소드를 이용하여 만든 MockHttpSession을 만화 저장을 수행하는 mockMvc의 session에 

넣어주면 된다.

@Test
@DisplayName("작가로 로그인하면 만화를 등록할 수 있습니다 - 성공")
void save() throws Exception {
    // given
    saveAuthorInRepository();
    MockHttpSession session = loginAuthorSession();

    CartoonSave cartoonSave = CartoonSave.builder()
            .title("만화 제목")
            .dayOfTheWeek("MON")
            .progress("SERIALIZATION")
            .build();

    String cartoonSaveJson = objectMapper.writeValueAsString(cartoonSave);

    // expected
    mockMvc.perform(post("/cartoon")
                    .session(session)
                    .contentType(APPLICATION_JSON)
                    .content(cartoonSaveJson))
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andDo(document("cartoon/save"));
}

이렇게 하면 정상적으로 테스트 코드가 성공하였다.  

하지만 이렇게 두 메소드를 만들어서 로그인이 필요한 테스트 케이스마다 앞에 두 줄씩 적어야 한다.  

움... 더 좋은 방법이 있을 것 같다.. 찾으면 다시 글을 작성해보겠다.