데이터베이스 연동_ 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
을 찾아서 설정으로 사용테스트와 데이터베이스 분리
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
을 쓰면 임베디드 모드로 동작하는 데이터베이스를 만들 수 있다주의
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