테스트에 필요한 인증 인가

황인우·2025년 2월 26일

프로젝트를 진행하면서

인가인증 파트를 맡아서 진행하다보니

테스트 코드나 이런 것들을 짜는 것이 수월하였다.


그러나 다른 팀들은 테스트 코드를 잘 짜도

인증을 제대로 하지 못해 403 오류로 실패하는 경우가 많았다.


그리고 우리 쪽 코드에서도 중복되는 부분이 많아서

따로 메서드로 분리하기로 하였다.


TestUserHelper.java

1. 기존 코드

@Test
@DisplayName("닉네임 변경")
void changeNickname() throws Exception {
    SiteUser actor = userService.findByUsername("user1").get();
    String actorAuthToken = userService.genAuthToken(actor);

    ResultActions resultActions = mvc
            .perform(
                    post("/api/user")
                            .header("Authorization", "Bearer " + actorAuthToken)
                            .content("""
                                        {
                                            "nickname": "changedNickname"
                                        }
                                        """.stripIndent()
                            )
                            .contentType(
                                    new MediaType(MediaType.APPLICATION_JSON, StandardCharsets.UTF_8)
                            )
            )
            .andDo(print());

    resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.resultCode").value("200-1"))
            .andExpect(jsonPath("$.msg").value("사용자 정보가 수정되었습니다."));

    assertThat(actor.getNickname()).isEqualTo("changedNickname");
}

2. 문제점

  1. 인증이 필요한 요청마다 사용자를 조회하고, 토큰을 생성하고,
    헤더에 부착하는 작업이 반복되고 있다.

  2. JSON과 UTF-8 인코딩으로 설정하는 부분이 반복되고 있다.

  3. 다른 팀은 이 모든 것을 정확하게 알기 어렵다.


3. 해결, TestUserHelper 클래스

@Component
public class TestUserHelper {

    private final UserService userService;
    private final MockMvc mvc;

    public TestUserHelper(UserService userService, MockMvc mvc) {
        this.userService = userService;
        this.mvc = mvc;
    }

    public ResultActions requestWithUserAuth(String username, MockHttpServletRequestBuilder request) throws Exception {
        SiteUser actor = userService.findByUsername(username).get();
        String actorAuthToken = userService.genAuthToken(actor);

        return mvc.perform(request
                .header("Authorization", "Bearer " + actorAuthToken)
                .contentType(new MediaType(MediaType.APPLICATION_JSON, StandardCharsets.UTF_8))
        ).andDo(print());
    }
}

인증이 필요한 코드에서 requestWithUserAuth 메서드를 호출하며

username과 해당 요청만 넘겨주면 되도록 하였다.


4. 사용 예시

이전의 코드를 helper 클래스와 메서드를 사용하면 이렇게 된다.

@Test
@DisplayName("닉네임 변경, TestUserHelper 테스트")
void changeNicknameAndUserHelperTest() throws Exception {
    String username = "user1";
    // 요청 생성
    MockHttpServletRequestBuilder request =
            post("/api/user")
                .content("""
                        {
                            "nickname": "changedNickname"
                        }
                        """.stripIndent());

    // 인증 원하는 username 과 요청으로 도우미 메서드 호출
    ResultActions resultActions = testUserHelper.requestWithUserAuth(username, request);

    // 결과 확인
    resultActions
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.resultCode").value("200-1"))
            .andExpect(jsonPath("$.msg").value("사용자 정보가 수정되었습니다."));

    SiteUser actor = userService.findByUsername(username).get();
    assertThat(actor.getNickname()).isEqualTo("changedNickname");
}


코드도 훨씬 간결해졌고

다른 팀에서도 잘 활용하여 테스트 중에서

인가인증 문제가 생기지 않게 되었다.

0개의 댓글