@Sql로 효율적인 테스트 데이터 셋업하기: JUnit 테스트에서 SQL 활용법

궁금하면 500원·2024년 11월 5일

미생의 스프링

목록 보기
19/48

Test 코드에서 @Sql을 활용한 기본 데이터 셋업

JUnit을 이용한 테스트에서는 종종 데이터베이스와 연동하여 테스트를 진행할 때, 반복적으로 필요한 데이터를 매번 셋업하는 과정이 필요합니다.
이때, @Sql 어노테이션을 활용하면 SQL 스크립트를 미리 작성해두고 테스트에서 손쉽게 데이터를 셋업할 수 있어 매우 유용합니다.

1. @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'이어야 합니다.");
    }
}

2. @Sql과 @Transactional의 결합

위 예시에서 @Transactional 어노테이션과 함께 사용하면, 테스트가 종료된 후 데이터베이스에서 수행된 모든 변경 사항이 롤백됩니다.
이를 통해 테스트 간의 데이터 격리가 보장되고, 테스트가 반복적으로 실행될 때마다 깨끗한 상태로 시작할 수 있습니다.

3. @Sql의 장점

매번 테스트 코드를 작성할 때마다 필요한 데이터를 셋업하는 것은 매우 번거롭고 반복적인 작업입니다.
하지만 @Sql을 사용하면 데이터 셋업을 SQL 파일로 미리 정의해두고, 테스트 클래스에서 해당 파일을 쉽게 참조하여 재사용할 수 있습니다.
이는 테스트 코드의 가독성을 높이고, 데이터 셋업의 일관성을 유지하는 데 도움을 줍니다.

4. 활용 팁

  • 데이터베이스 초기화가 필요한 테스트를 작성할 때, @Sql을 활용하여 데이터를 미리 준비해두면 테스트가 실행될 때마다 동일한 데이터가 셋업됩니다.

  • 테스트 코드가 복잡해질수록, 테스트 전용 데이터셋을 SQL 파일로 분리하여 관리하는 것이 유지보수에 유리합니다.

  • 데이터베이스 상태를 변경해야 하는 테스트에서는 @Transactional을 결합하여, 테스트 종료 후 변경 사항을 자동으로 롤백하는 것이 좋습니다.

결론

@Sql@Transactional을 활용하면, 테스트의 데이터 셋업을 훨씬 효율적으로 관리할 수 있습니다.
이렇게 미리 설정된 SQL 스크립트를 재사용하면서, 테스트 코드 작성의 효율성과 가독성을 높일 수 있습니다.
매번 데이터를 수동으로 셋업하던 번거로움을 줄이고, 더 나은 테스트 환경을 구축할 수 있습니다.

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글