[Spring Boot] 테스트 코드

민채·2025년 1월 21일
1

SpringBoot

목록 보기
3/3

사용 이유

  • 테스트 코드를 사용하면 코드 결과 검증을 쉽게 할 수 있음
    • 사용하지 않는 경우
      1. 코드 작성

      2. 애플리케이션 실행

      3. Request 요청

      4. 로그 또는 print로 결과 검증

      5. 에러 발생 또는 원하는 결과가 아닌 경우 종료

      6. 다시 코드 작성

        위와 같은 과정이 반복된다면 비용이 많이 발생

    • 사용하는 경우
      1. 테스트 코드 작성

      2. 테스트 코드 실행

      3. 결과 검증

      4. 테스트 코드 수정

        테스트 코드를 사용하면 애플리케이션을 실행하고 종료할 필요가 없음

  • 테스트 코드를 사용하지 않으면 어느 계층에서 문제가 발생했는지 파악하는 데 많은 시간이 든다.
  • 하지만 테스트 코드를 통해 계층 별로 테스트를 진행한다면 어느 부분에서 잘못됐는지 쉽게 파악할 수 있다.
  • 테스트 코드를 작성할 때는 정상적으로 동작하는 지 확인할 때도 잘 쓰이지만 예외가 발생했을 때 유용하게 쓰임

종류

단위 테스트

장점

  • 새로운 기능에 대해서 빠르게 작성 가능
  • Test 코드 자체가 하나의 문서
  • 시간과 비용의 절감

단점

  • 독립적인 테스트이므로 다른 객체와 상호작용 처리를 위해서 가짜 객체 정의가 필요
  • 가짜 객체의 답변 작성 필요함
  • 실제 운영 환경과 다른 답변을 내놓을 수 있는 가능성이 있음

통합 테스트

장점

  • 실제 객체를 사용하므로 가짜 객체 사용하지 않아 정의하지 않아도 됨
  • 실제 운영 환경과 같은 값을 도출 가능함

단점

  • 테스트 하나에 많은 비용이 들어감
  • 어느 계층에서 발생한 문제인지 파악하기 힘듦

주의할 점

  • 1개의 테스트는 1개의 기능에 대해서만 테스트 하는 것이 좋음
  • 테스트 주체와 협력자를 구분하기. ( 여기서 주체는 테스트를 할 객체이며, 협력자는 테스트를 진행하기 위해 정의하는 가짜 객체)
  • Given, when, then으로 명확하게 작성하기
    • Given: 테스트를 진행할 행위를 위한 사전 준비
    • when: 테스트를 진행할 행위
    • then: 테스트를 진행한 행위에 대한 결과 검증

Junit

  1. Java에서 독립된 단위 테스트를 지원해주는 프레임워크

  2. Assert(검증)을 이용해서 결과를 기댓값과 실제 값을 비교

  3. @Test 어노테이션마다 독립적으로 테스트가 진행

Springboot Test

spring-boot-test-starter 구성요소

  1. spring-boot-test: 테스트에 필요한 핵심 기능 라이브러리

  2. spring-boot-test-autoconfigure: 테스트 진행 위한 Configuration 라이브러리

  • 스프링에서는 다음과 같이 test 폴더 밑에 테스트 코드를 따로 만들 수 있다.

image.png

테스트 코드 작성하지 않고 바로 실제 코드만 작성한 경우

테스트 코드 작성하지 않고 바로 실제 코드만 작성한 경우

단위 테스트

도메인 테스트

  • 예시 코드
package com.ssafy.user.dto.entity;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

// @DataJpaTest -> JPA 사용 시 붙이기
class UserDomainTest {
    @Test
    @DisplayName("사용자 생성 테스트")
    void createMember() {
        // given
        User user = User.builder().loginId("test").nickname("name").build();

        // when, then
        Assertions.assertThat(user.getLoginId()).isEqualTo("test");
        Assertions.assertThat(user.getNickname()).isEqualTo("name");
    }

    @Test
    @DisplayName("사용자의 닉네임 바뀌는지 확인하는 테스트")
    void changeNicknameTest(){
        // given
        User user = User.builder().loginId("test").nickname("name").build();

        // when
        user.changeNickname("newName");

        // then
//        Assertions.assertThat(user.getNickname()).isEqualTo("newName");
        Assertions.assertThat(user.getNickname()).isEqualTo("change");
    }
}
  • @Test

    • 반드시 필요
    • 반환하는 것이 없도록 void여야 함
  • @DisplayName

    • 테스트 진행 시 나오는 테스트명을 정할 수 있음
  • 실행 결과

    image.png

    image.png

    image.png

    image.png

  • 동시에 실행도 가능 → 모두 독립적으로 실행되기에 같이 돌려도 결과에 미치는 영향은 없음

  • JPA를 사용하는 경우

    • @DataJpaTest 사용 (클래스에 붙이는 것)
      • @Transaction을 포함하고 있어서 1개 의 테스트가 끝나면 Rollback → 다른 테스트에게 영향을 미치지 않음
      • DataSource에 대한 설정
      • CRUD가 제대로 동작하는지 확인

서비스 테스트

  • 예시 코드
ExtendWith(SpringExtension.class)
public class UserServiceTest {
 
    // Test 주체
    UserService userService;
 
    // Test 협력자
    @MockBean
    UserDao userDao;
 
    // Test를 실행하기 전마다 UserService 에 가짜 객체를 주입
    @BeforeEach
    void setUp() {
        userService= new userService(userDao);
    }
    
    
}
  • 서비스 계층은 Repository 계층의 객체를 스프링에게 주입받고 있음
  • 서비스 계층의 테스트 주체는 서비스 객체, 협력자는 Repository 객체
  • Repository 는 가짜 객체로써 응답 설정해줘야 함
  • Junit5 기능을 사용
  • Test에서 가짜 객체를 사용 → @ExtendWith(SpringExtension.class)를 붙이기
  • @BeforeEach
    • Test를 실행하기 전 항상 실행하도록 하는 역할
    • ex) 가짜 객체를 주입하는 데 사용
  • @MockBean
    • 가짜 객체를 만드는 역할 → 가짜 객체이므로 응답을 정의해줘야 함
    • Test의 협력자 역할을 함

컨트롤러 테스트

  • ControllerAdvice, Filter 등을 포함시키거나 제외 시킬 수 있음
  • Security에 대한 Test도 가능
  • 예시 코드
@WebMvcTest(UserController.class)
public class UserControllerTest {
 
    @Autowired
    MockMvc mvc;
 
    @MockBean
    UserService userService;

}
  • 클래스 위에 @WebMvcTest ****붙이기
    • MVC를 위한 테스트
    • 컨트롤러가 설계대로 동작하는 지에 대해 검증하는데 필요
    • @WebMvcTest(UserController.class) : 테스트 주체 작성 가능
    • Controller를 구체적으로 적을 수 있음
  • @MockBean : 테스트 협력자 위에 붙이기 → 컨트롤러를 테스트 할 경우에는 서비스를 협력자로 등록
  • MockMvc는 실제로 서블릿 컨테이너를 사용하지 않고, 테스트용으로 MVC 기능을 사용할 수 있게 해주는 역할
    • 테스트 때 생성되는 WebApplicationContext에서 주입 받음
profile
코딩계의 떠오르는 태양☀️

0개의 댓글

관련 채용 정보