데이터베이스 연결 테스트

이동건 (불꽃냥펀치)·2025년 2월 25일
0

데이터베이스 연동_ main_application.properties

properties
 spring.profiles.active=local
 spring.datasource.url=jdbc:h2:tcp://localhost/~/test
 spring.datasource.username=sa
logging.level.org.springframework.jdbc=debug

데이터베이스 연동_test_application.properties

properties
 spring.profiles.active=test
 spring.datasource.url=jdbc:h2:tcp://localhost/~/test
 spring.datasource.username=sa
logging.level.org.springframework.jdbc=debug

@SpringbootTest

  • @SpringbootTest @SpringbootApplication을 찾아서 설정으로 사용

테스트와 데이터베이스 분리

  • H2 데이터베이스를 용도에 따라 2가지로 구분
    • jdbc:h2:tcp://localhost/~/test local에 접근하는 서버 전용 데이터베이스
    • jdbc:h2:tcp://localhost/~/testcase test 케이스에서 사용하는 전용 데이터베이스



테스트 데이터 롤백

테스트가 끝나고 나서 트랜잭션을 강제로 롤백하면 데이터가 깔끔하게 제거된다. 데이터를 이미 저장했는데 중간에 테스트가 실패해서 롤백을 호출하지 못하더라도 상관 없다. 트랜잭션을 커밋하지 않았기 때문에 데이터베이스에 해당 내용이 반영되지 않음

테스트는 각각의 테스트 실행 전 후로 동작하는 @BeforeEach @AfterEach라는 편리한 기능을 제공

테스트에 직접 트랜잭션 추가

@SpringBootTest
 class ItemRepositoryTest {
     @Autowired
     ItemRepository itemRepository;
      //트랜잭션 관련 코드
      @Autowired
      PlatformTransactionManager transactionManager;
      TransactionStatus status;
      @BeforeEach
      void beforeEach() {
      //트랜잭션 시작
             status = transactionManager.getTransaction(new
      		 DefaultTransactionDefinition());
      }
      @AfterEach
      void afterEach() {
      	//MemoryItemRepository 의 경우 제한적으로 사용
      	if (itemRepository instanceof MemoryItemRepository) {
                   ((MemoryItemRepository) itemRepository).clearStore();
               }
      //트랜잭션 롤백
               transactionManager.rollback(status);
           }
      //...
}
  • @BeforeEach: 각각의 테스트 케이스를 실행하기 직전에 호출함 따라서 요기서 트랜잭션을 시작하면 각각의 테스트를 트랜잭션 범위 안에서 실행할 수 있다
  • @AfterEach: 각각의 테스트 케이스가 완료된 직후에 호출 됨 따라서 여기서 롤백하면 데이터를 트랜잭션 실행 전 상태로 복구가 가능



테스트에서 @Transactional

  • 스프링에서 제공하는 @Transactional 에노테이션은 로직이 성공적으로 수행되면 커밋되도록 동작함
  • @Transactional을 테스트에서 사용하면 테스트를 트랜잭션 안에서 실행하고 테스트가 끝나면 트랜잭션을 커밋하는 것이 아닌 자동으로 롤백해버림
  • 롤백으로 테스트 검증이 완료된 후에는 데이터가 삭제

강제로 커밋하기_ @Commit
@Transactional을 테스트에서 사용하면 롤백이 되어버리기 때문에 데이터가 실제로 저장되었는지 확인하는 것이 어렵다. 실제로 데이터가 직접 저장되는지 여부를 확인하려면 @Commit을 클래스 또는 메서드에 붙이면 롤백대신 커밋이 호출된다. 참고로 @Rollback(value=false)를 사용해도 됨




테스트_임베디드 모드

테스트 케이스를 실행하기 위해서 데이터베이스를 별도로 설치하고 운영하는 것은 상당히 번잡스럽다. 단순히 테스트를 검증할 용도로만 사용하므로 테스트가 끝나면 데이터베이스를 아예 지워버려도 된다.

	 @Bean
     @Profile("test")
     public DataSource dataSource() {
		log.info("메모리 데이터베이스 초기화");
          DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        return dataSource;
    }
  • 프로필이 test인 경우에만 해당 데이터베이스를 사용하도록 설정
  • 테스트케이스에서만 이 데이터소스를 스프링 빈으로 등록해서 사용하겠다는 뜻
  • jdbc:h2:mem:db 을 쓰면 임베디드 모드로 동작하는 데이터베이스를 만들 수 있다

주의

  • 메모리 DB는 애플리케이션이 종료될 때 함께 사라지기 때문에 애플리케이션 실행 시점에 데이터베이스 테이블도 새로 만들어 줘야 함
  • src/test/resources/schema.sql에 원하는 데이터베이스를 만들면 이 문제가 해결
 drop table if exists item CASCADE;
 create table item
 (
     id        bigint generated by default as identity,
     item_name varchar(10),
     price     integer,
     quantity  integer,
     primary key (id)
 );

출처:https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-2

profile
자바를 사랑합니다

0개의 댓글

관련 채용 정보