본문 바로가기
BackEnd/Project

[SNS] Ch03. 좋아요 기능 테스트 작성

by 개발 Blog 2024. 9. 9.

공부 내용을 정리하고 앞으로의 학습에 이해를 돕기 위해 작성합니다.

 

좋아요 기능은 사용자가 특정 게시물에 좋아요 버튼을 누르면 해당 게시물의 좋아요 카운트가 증가하는 기능이다. SNS에서 많이 사용되는 이 기능은 사용자 인터랙션을 증가시키며, 각 게시물의 인기도를 측정할 수 있는 중요한 요소다.

시퀀스 다이어 그램 설명

  1. 클라이언트에서 서버로 좋아요 요청을 보낸다.
  2. 서버는 데이터베이스에 해당 게시물에 대한 업데이트 요청을 보낸다.
  3. 데이터베이스가 성공적으로 업데이트되면 서버에 성공 메시지를 반환한다.
  4. 서버는 클라이언트에 성공 메시지를 반환한다.
  5. 만약 로그인하지 않은 사용자가 요청을 보냈을 경우, 서버는 실패 메시지를 반환한다.
  6. 데이터베이스 오류나 게시물이 존재하지 않는 경우에도 서버는 적절한 실패 메시지를 반환한다.

AuthenticationConfig 수정 

좋아요 기능 테스트 코드를 작성하기 전에, 먼저 AuthenticationConfig 코드를 수정해야 한다. 이 수정은 애플리케이션이 실행될 때, 프론트엔드 코드와 함께 jar 파일로 빌드되어 브라우저에서 실행될 때의 요청 처리와 관련이 있다. 예를 들어 브라우저에서 localhost:8080/feed/feed로 요청을 보내면, 이 요청이 애플리케이션으로 들어오게 된다. 모든 요청마다 헤더를 확인하여 토큰이 올바른지, 사용자가 누구인지 체크해야 한다.

 

이러한 동작을 개선하기 위해, 정규식을 이용해 API 요청에 대해서만 인증 로직이 동작하도록 수정할 필요가 있다.

package com.example.sns.configuration;

import com.example.sns.configuration.filter.JwtTokenFilter;
import com.example.sns.exception.CustomAuthenticationEntryPoint;
import com.example.sns.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class AuthenticationConfig extends WebSecurityConfigurerAdapter {

    private final UserService userService;

    @Value("${jwt.secret-key}")
    private String key;
	
    //추가
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().regexMatchers("^(?!/api/).*");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/*/users/join", "/api/*/users/login").permitAll()
                .antMatchers("/api/**").authenticated()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilterBefore(new JwtTokenFilter(key, userService), UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling()
                .authenticationEntryPoint(new CustomAuthenticationEntryPoint());
    }
}
  • API 요청에만 JWT 인증을 적용하도록 regexMatchers("^(?!/api/).*") 부분을 추가했다. 이로 인해, /api/로 시작하지 않는 요청은 JWT 인증 없이 처리된다.

테스트 코드 작성

PostControllerTest

PostControllerTest에 테스트 메서드를 추가한다. 이 테스트 코드는 세 가지 시나리오를 다룬다.

  @Test
  @WithMockUser
  void 좋아요기능() throws Exception {
      mockMvc.perform(post("/api/v1/posts/1/likes")
                      .contentType(MediaType.APPLICATION_JSON)
              ).andDo(print())
              .andExpect(status().isOk());
  }

  @Test
  @WithAnonymousUser
  void 좋아요버튼클릭시_로그인하지_않은경우() throws Exception {
      mockMvc.perform(post("/api/v1/posts/1/likes")
                      .contentType(MediaType.APPLICATION_JSON)
              ).andDo(print())
              .andExpect(status().isUnauthorized());
  }

  @Test
  @WithAnonymousUser
  void 좋아요버튼클릭시_게시물이_없는경우() throws Exception {
      doThrow(new SnsApplicationException(ErrorCode.POST_NOT_FOUND)).when(postService).like(any(), any());

      mockMvc.perform(post("/api/v1/posts/1/likes")
                      .contentType(MediaType.APPLICATION_JSON)
              ).andDo(print())
              .andExpect(status().isNotFound());
  }

좋아요기능()

 

  • 로그인된 사용자가 게시물에 좋아요 요청을 보낸다.
    POST /api/v1/posts/1/likes 요청이 성공적으로 처리되어 200 OK 상태 코드를 반환하는지 테스트한다.
    @WithMockUser로 로그인 상태를 시뮬레이션한다.

좋아요버튼클릭시_로그인하지_않은경우()

  • 로그인하지 않은 사용자가 좋아요를 요청한다.
    POST /api/v1/posts/1/likes 요청에 대해 401 Unauthorized 상태가 반환되는지 확인한다.
    @WithAnonymousUser로 익명 사용자 상태를 시뮬레이션한다.

좋아요버튼클릭시_게시물이_없는경우()

 

  • 존재하지 않는 게시물에 좋아요 요청을 보낸다.
    POST_NOT_FOUND 예외를 발생시켜, 404 Not Found 상태가 반환되는지 테스트한다.
    doThrow()를 사용해 postService.like() 호출 시 예외를 시뮬레이션한다.

PostService 코드 수정

PostService에 좋아요 기능을 담당할 like 메서드를 추가한다.

@Transactional
public void like(Integer postId, String userName) {
    // 좋아요 기능 로직 작성
}
  • 이 메서드는 게시물 ID와 사용자 이름을 받아, 데이터베이스에서 해당 게시물에 대한 좋아요 카운트를 증가시키는 역할을 한다.