공부함

테스트 더미데이터 삽입 방법 본문

테스트

테스트 더미데이터 삽입 방법

찌땀 2024. 10. 21. 17:59

DB와 연동한 통합 테스트 코드 작성 시 더미데이터가 필요한 경우가 있다. 상황에 따른 더미데이터 삽입 방법을 알아보자.

orm 활용

mybatis, jpa와 같은 orm을 사용해 더미데이터를 삽입한다. orm을 통한 삽입 기능이 열려있어야 한다. 사이드프로젝트를 진행 할 때는 상품 데이터를 CRUD하는 기능을 한 프로젝트에 다 만들었다. 하지만 실무에서는 꼭 그렇다는 보장이 없다. web을 통해서는 상품 CRUD가 가능하지만, api는 상품 배송 승인, 반려에만 사용된다면 CREATE 기능은 굳이 개발하지 않을 수 있다. 테스트 시 더미데이터 삽입을 위해 CREATE 기능을 추가할 순 없다. 사용하지 않는 기능을 테스트를 위해 추가하는 것은 배보다 배꼽이 커지는 일이다. 취약점, 버그가 발생할 수 있고 추가한 기능 또한 테스트 해야 한다. 

 

모든 테스트 메서드에 더미데이터가 필요한 것은 아니었기 때문에 효율을 위해 애노테이션을 만들어 더미가 필요한 테스트 메서드에 달아줬다. 

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InsertDummy {
}

 

더미데이터는 @BeforeEach를 활용해 삽입했다. 테스트 상에서 데이터를 삽입, 변경, 삭제 없이 조회만 한다면 테스트 컨텍스트 생성 시 최초에만 삽입하는게 효율적이겠지만, 그게 아니기 때문에 매 메서드 전에 더미를 삽입하고, @Transactional로 롤백하도록 했다.

sql 활용

api 테스트 시에는 ORM을 활용해 더미를 삽입할 수 없었다. 상품을 검증하는 기능을 테스트 하기 위해 상품 더미를 넣으려고 해도 api로는 상품등록을 하지 않아 기능이 없는 상황인 것이다. 위에서 말했듯이 테스트를 위해 상품 등록 기능을 추가할 수는 없다. 나는 .sql 파일을 활용해 더미데이터를 삽입하는 방식을 택했다. sql 파일은 resource 아래에 data.sql로 작명하면 스프링에서 자동적으로 실행해준다. 또는 @Sql(scripts = 경로, .. )와 같이 직접 설정할 수도 있다. 

 

data.sql 파일에 아래와 같이 더미데이터 삽입 INSERT 문을 작성해준다. 

INSERT INTO product(id, name, price) 
VALUES (123123, '신라면', 4000);
INSERT INTO product(id, name, price)
VALUES (123412, '진라면', 3000);
INSERT INTO product(id, name, price)
VALUES (123231, '신라면 블랙', 7000);

 

더미데이터 관리 

두 방법 중 어느 방법이 더 좋을까? 나는 더미데이터 관리 측면에서 orm 방법이 더 뛰어나다고 생각한다. 

public class ProductDummy {

    public static final Product 신라면 = ProductFixture.builder()
            .id(123123L)
            .name("신라면")
            .price(2500)
            .build();

    public static final Product 진라면 = ProductFixture.builder()
            .id(123124L)
            .name("진라면")
            .price(2300)
            .build();
}

 

삽입한 더미데이터를 테스트 코드에서 활용하기 위해 상수로 만들어 별도 파일에 관리했다.

// 검증 시 
	assertThat(actualPrice).isEqualTo(신라면.getPrice());

// 삽입 시 
	productRepository.insert(신라면);

dao를 활용해 더미데이터를 삽입하면 더미데이터 삽입, 검증 등 더미데이터가 필요한 java 코드에서 상수 파일을 통해 더미데이터 객체 또는 값을 참조할 수 있다. 더미데이터 관련 수정사항이 있다면 상수파일 ProductDummy만 수정하면 된다. 

// 검증 시 
    assertThat(actualPrice).isEqualTo(신라면.getPrice());

// 삽입 시 data.sql
    INSERT INTO product(id, name, price) 
    VALUES (123123, '신라면', 4000); <-- 하드코딩된 값

sql 파일을 사용할 경우 삽입 시에는 하드코딩된 값을 사용한다. 더미데이터 관련 수정 사항이 있다면 ProductDummy와 data.sql 파일을 모두 수정해 줘야 한다. 즉 더미 데이터를 하나의 파일에서 관리하지 못한다.

java 코드상에서 동적으로 sql을 작성할 수도 있지만 native sql이 java 코드상에 노출되고 코드가 매우 지저분해진다.. 

 

요약

  • 더미데이터는 상수 파일로 관리하자. 
  • orm을 활용한 삽입이 가능하면 채택하고, 아니라면 sql 파일로 삽입하자.
  • 더미데이터 삽입을 위해 삽입 기능을 추가하지 말자.

글을 쓰기 전에는 쓸 내용이 많았는데, 막상 쓰다보니 정리가 되어 내용이 많이 간단해졌다. api에 CREATE 기능이 없다던가 하는 특수한 상황을 예로 들었는데 (특수한가? 잘 모르겠다..) 최고의 공격수는 모든 패스를 골로 연결하듯이 좋은 개발자는 특수한 상황에서도 알맞은 코드를 짤 수 있어야 한다고 생각한다. 

 

  

'테스트' 카테고리의 다른 글

@ParameterizedTest를 사용해보자  (0) 2024.10.31
테스트 환경 (@SpringBootTest와 @WebMvcTest)  (1) 2024.09.08