[Spring]테스트 코드 기본 어노테이션 및 생명주기

WOOK JONG KIM·2022년 10월 29일
0
post-thumbnail

우선 앞서 만든 프로젝트의 일부를 가져오고 ProductServiceImpl와 Product entity 클래스를 수정하였음

@Service
public class ProductServiceImpl implements ProductService {

    private final Logger LOGGER = LoggerFactory.getLogger(ProductServiceImpl.class);
    private final ProductRepository productRepository;

    @Autowired
    public ProductServiceImpl(ProductRepository productRepository){
        this.productRepository = productRepository;
    }

    @Override
    public ProductResponseDto getProduct(Long number) {
        LOGGER.info("[getProduct] input Number : {}", number);
        Product product = productRepository.findById(number).get();

        LOGGER.info("[getProduct] product number : {}, name : {}", product.getNumber(),
                product.getName());
        ProductResponseDto productResponseDto = new ProductResponseDto();
        productResponseDto.setNumber(product.getNumber());
        productResponseDto.setName(product.getName());
        productResponseDto.setPrice(product.getPrice());
        productResponseDto.setStock(product.getStock());

        return productResponseDto;
    }

    @Override
    public ProductResponseDto saveProduct(ProductDto productDto) {
        LOGGER.info("[saveProduct productDTO : {}", productDto.toString());
        Product product = new Product();
        product.setName(productDto.getName());
        product.setPrice(productDto.getPrice());
        product.setStock(productDto.getStock());

        Product savedProduct = productRepository.save(product);
        LOGGER.info("[saveProduct] saveProduct : {}", savedProduct);

        ProductResponseDto productResponseDto = new ProductResponseDto();
        productResponseDto.setNumber(savedProduct.getNumber());
        productResponseDto.setName(savedProduct.getName());
        productResponseDto.setPrice(savedProduct.getPrice());
        productResponseDto.setStock(savedProduct.getStock());

        return productResponseDto;
    }

    @Override
    public ProductResponseDto changeProductName(Long number, String name) {
        Product foundProduct = productRepository.findById(number).get();
        foundProduct.setName(name);
        Product changeProduct = productRepository.save(foundProduct);

        ProductResponseDto productResponseDto = new ProductResponseDto();
        productResponseDto.setNumber(changeProduct.getNumber());
        productResponseDto.setName(changeProduct.getName());
        productResponseDto.setPrice(changeProduct.getPrice());
        productResponseDto.setStock(changeProduct.getStock());

        return productResponseDto;
    }

    @Override
    public void deleteProduct(Long number) {
        productRepository.deleteById(number);
    }
}

DAO를 따로 두지 않고 서비스 레이어에서 바로 Repository를 사용하는 구조로 바꾸었음

그리고 Product 엔티티 클래스에 어노테이션 추가하였음

package com.springboot.test.data.entity;

import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString(exclude = "name")
@Table(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long number;

    @Column(nullable=false)
    private String name;

    @Column(nullable = false)
    private Integer price;

    @Column(nullable = false)
    private Integer stock;

    private LocalDateTime createdAt;

    private LocalDateTime updatedAt;

}

스프링 부트의 테스트 설정

스프링 부트는 테스트 환경 설정을 위해 spring-boot-starter-test 프로젝트 지원
-> pom.xml에 의존성 추가하자

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
</dependency>

스프링 부트에서 제공하는 spring-boot-starter-test 라이브러리는 JUnit, Mockito, assertJ 등이 있다

대표적 라이브러리

  • JUnit 5 : 자바 애플리케이션의 단위 테스트 지원
  • Spring Test & Spring Boot test : 스프링 부트 애플리케이션에 대한 유틸리티와 통합 테스트 지원
  • AssertJ : 다양한 Assert문을 지원하는 라이브러리
  • Hamcrest : Matcher를 지원하는 라이브러리
  • Mockito : 자바 Mock 객체를 지원하는 프레임웍
  • JSONassert : JSON용 단정문 라이브러리
  • JsonPath : JSON용 XPath 지원

JUnit 생명 주기

관련 어노테이션

  • @Test : 테스트 코드를 포함한 메서드 정의
  • @BeforeAll : 테스트를 시작하기 전에 호출되는 메서드 정의
  • @BeforeEach : 각 테스트 메서드가 실행되기 전에 동작하는 메서드 정의
  • @AfterAll : 테스트를 종료하면서 호출되는 메서드 정의
  • @AfterEach : 각 테스트 메서드가 종료되면서 호출되는 메서드 정의
package com.springboot.test;

import org.junit.jupiter.api.*;

public class TestLifeCycle {

    @BeforeAll
    static void beforeAll(){
        System.out.println("## BeforeAll Annotation 호출 ##");
        System.out.println();
    }

    @AfterAll
    static void afterAll(){
        System.out.println("## AfterAll Annotation 호출 ##");
        System.out.println();
    }

    @BeforeEach
    void beforeEach(){
        System.out.println("## BeforeEach Annotation 호출 ##");
        System.out.println();
    }

    @AfterEach
    void afterEach(){
        System.out.println("## AfterEach Annotation 호출 ##");
        System.out.println();
    }

    @Test
    void test1(){
        System.out.println("## test1 시작 ##");
        System.out.println();
    }

    @Test
    @DisplayName("Test Case 2!!")
    void test2(){
        System.out.println("## test2 시작 ##");
        System.out.println();
    }

    @Test
    @Disabled
    void test3(){
        System.out.println("## test3 시작 ##");
        System.out.println();
    }
}
## BeforeAll Annotation 호출 ##

## BeforeEach Annotation 호출 ##

## test1 시작 ##

## AfterEach Annotation 호출 ##

## BeforeEach Annotation 호출 ##

## test2 시작 ##

## AfterEach Annotation 호출 ##


void com.springboot.test.TestLifeCycle.test3() is @Disabled
## AfterAll Annotation 호출 ##

@BeforeAll 과 @AfterAll 어노테이션이 지정된 메서드는 전체 테스트 동작에서 처음과 마지막에 수행

@BeforeEach, @AfterEach는 각 테스트가 실행될 때 @Test 어노테이션이 지정된 테스트 메서드를 기준으로 실행

@Disabled는 실행되지 않음 -> 각 Each들이 실행되지 않았음

profile
Journey for Backend Developer

0개의 댓글