본문 바로가기

Backend Development/Spring boot

[Spring boot] Spring Boot Test Sql script 활용하기

Backend api 개발 시 Spring boot test로 Unittest를 많이 하게 된다. 그러나 항상 고민하는게 실제 Insert 나 Update로 특정 DB 상태를 바꿀 시 다음 테스트에 영향을 준다는 것이다. 각각의 테스트 메소드가 종료시점에 해당 테스트에서 변경된 내용을 돌려줄 수 있으나 정리 로직을 추가하는것은 테스트 본연의 목표와 다른 부가 작업일 뿐이다.

 

Spring Boot Test 에서는 각 메소드 실행 전후로 외부 sql script를 실행할 수 있게 설정을 가지고 있다. 간단하게 메소드 전에 DB 데이터들을 삽입하고 메소드 실행 후에 DB 데이터 전체를 지우도록 하면 중간에 테스트 도중 들어가거나 변경된 내용들도 손쉽게 리셋하는 효과를 가질수 있다.

 

Unittest 설정 예시

import com.sdp.SdpApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SdpApplication.class)
@Sql(
    scripts = {"classpath:testdata/getDatal.sql"},
    config = @SqlConfig(dataSource = "dataSource", transactionManager = "transactionManagerTest"),
    executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD

)
@Sql(
    scripts = {"classpath:testdata/removeData.sql"},
    config = @SqlConfig(dataSource = "dataSource", transactionManager = "transactionManagerTest"),
    executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD

)
@TestPropertySource(properties = {"spring.profiles.active=uniittest"})
public class TestCustomer {

    @Test
    public void insertTest() {
        // insert후 삭제 하지 않아도 됨
    }

 

Datasource config 예시

@Configuration
@MapperScan(basePackages = {"com.sdp.common", "com.sdp.mapper"}, sqlSessionFactoryRef="sdpSqlSessionFactory" )
public class SdpDataSourceConfig {
   
   @Bean(name="dataSource", destroyMethod="close")
   @Primary
   @ConfigurationProperties(prefix="spring.sdp.datasource")
   public DataSource sdpDataSource() {
      return DataSourceBuilder.create().build();
   }
   
  ... 중략

   @Bean("transactionManagerTest")
   public DataSourceTransactionManager transactionManagerTest() {
      DataSourceTransactionManager dstm = new DataSourceTransactionManager();
      dstm.setDataSource(sdpDataSource());
      return dstm;
   }
}

 

@Sql 어노테이션 추가로 sql 스크립트 실행 설정을 할 수 있다. 시작 전에 data용 스크립트와 삭제용 스크립트 파일을 준비하고 resource 하위에 폴더 지정해서 복사해 둔다.

 

그리고 아래와 같이 @Sql 어노테이션을 붙여 준다.

 

@Sql(
    scripts = {"classpath:testdata/getDatal.sql"},
    config = @SqlConfig(dataSource = "dataSource", transactionManager = "transactionManagerTest"),
    executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD
)

 

sciprts 항목에 실행할 스크립트 파일을 지정한다.

config 항목에는 테스트 실행시 사용할 DB Datasource 와 TransactionManager bean을 지정한다.

 

보통 DataSource bean은 @Configuration 클래스로 지정을 하므로 본인 프로젝트에 설정된 빈을 사용하도록 한다. (위 예제 소스 참조)

 

executionPhase에서는 두가지 옵션이 있다. BEFORE_TEST_METHOD, AFTER_TEST_METHOD 두가지 를 스프링에서 제공하고 있다. BEFORE 시에 데이터 준비를 하고 AFTER시에 정리를 하면 될 것이다.

 

최종적으로 위와 같이 설정 후 개별 Unittest method를 실행하면 실행전에 BEFORE로 지정한 스크립트가 실행되고 Unittest 수행 후 AFTER로 실행한 스크립트가 최종 실행되고 종료되게 된다.

 

-- The end --