
JUnit을 이용한 테스트에서는 종종 데이터베이스와 연동하여 테스트를 진행할 때, 반복적으로 필요한 데이터를 매번 셋업하는 과정이 필요합니다.
이때, @Sql 어노테이션을 활용하면 SQL 스크립트를 미리 작성해두고 테스트에서 손쉽게 데이터를 셋업할 수 있어 매우 유용합니다.
아래와 같이 @Sql을 활용하면, 테스트 클래스에서 미리 정의해놓은 SQL 스크립트를 자동으로 실행하여 필요한 데이터를 셋업할 수 있습니다.
-- test/resources/sql/data-setting.sql
INSERT INTO domain (type, id, name)
VALUES
('A', 1, 'test-1'),
('B', 2, 'test-2');
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@SpringBootTest
@Sql(scripts = {"classpath:sql/data-setting.sql"}) // SQL 스크립트 실행
@Transactional // 테스트 종료 후 롤백
public class RepositoryTest {
@Autowired
private MyRepository myRepository; // 테스트할 레포지토리 주입
@Test
void testRepositoryData() {
// 데이터베이스에서 삽입된 데이터를 조회
Long count = myRepository.count(); // domain 테이블의 레코드 개수를 조회
// 삽입된 데이터가 2개여야 하므로, 2와 비교하여 테스트 성공 여부 판단
assertEquals(2, count, "domain 테이블에 2개의 레코드가 있어야 합니다.");
// 데이터베이스에서 특정 ID로 레코드를 조회
DomainEntity domain = myRepository.findById(1L).orElse(null);
assertNotNull(domain, "ID가 1인 레코드는 반드시 존재해야 합니다.");
assertEquals("A", domain.getType(), "type은 'A'여야 합니다.");
assertEquals("test-1", domain.getName(), "name은 'test-1'이어야 합니다.");
// 다른 레코드도 조회하여 검증
DomainEntity domain2 = myRepository.findById(2L).orElse(null);
assertNotNull(domain2, "ID가 2인 레코드는 반드시 존재해야 합니다.");
assertEquals("B", domain2.getType(), "type은 'B'여야 합니다.");
assertEquals("test-2", domain2.getName(), "name은 'test-2'이어야 합니다.");
}
}
위 예시에서 @Transactional 어노테이션과 함께 사용하면, 테스트가 종료된 후 데이터베이스에서 수행된 모든 변경 사항이 롤백됩니다.
이를 통해 테스트 간의 데이터 격리가 보장되고, 테스트가 반복적으로 실행될 때마다 깨끗한 상태로 시작할 수 있습니다.
매번 테스트 코드를 작성할 때마다 필요한 데이터를 셋업하는 것은 매우 번거롭고 반복적인 작업입니다.
하지만 @Sql을 사용하면 데이터 셋업을 SQL 파일로 미리 정의해두고, 테스트 클래스에서 해당 파일을 쉽게 참조하여 재사용할 수 있습니다.
이는 테스트 코드의 가독성을 높이고, 데이터 셋업의 일관성을 유지하는 데 도움을 줍니다.
데이터베이스 초기화가 필요한 테스트를 작성할 때, @Sql을 활용하여 데이터를 미리 준비해두면 테스트가 실행될 때마다 동일한 데이터가 셋업됩니다.
테스트 코드가 복잡해질수록, 테스트 전용 데이터셋을 SQL 파일로 분리하여 관리하는 것이 유지보수에 유리합니다.
데이터베이스 상태를 변경해야 하는 테스트에서는 @Transactional을 결합하여, 테스트 종료 후 변경 사항을 자동으로 롤백하는 것이 좋습니다.
@Sql과 @Transactional을 활용하면, 테스트의 데이터 셋업을 훨씬 효율적으로 관리할 수 있습니다.
이렇게 미리 설정된 SQL 스크립트를 재사용하면서, 테스트 코드 작성의 효율성과 가독성을 높일 수 있습니다.
매번 데이터를 수동으로 셋업하던 번거로움을 줄이고, 더 나은 테스트 환경을 구축할 수 있습니다.