[우아한테크코스] 10월 6일 TIL
[Spring] 인수테스트 격리하기
-
@Transactional 적용
@SpringBootTest 어노테이션에 포트번호를 지정해 서버를 띄우는데 이때 http client와 서버의 로직이 서로 다른 thread에서 실행돼 롤백이 걸려도 다른 스레드에서 실행되어 db를 롤백하지 않는다.
-
테스트 종료 시 @AfterEach로 데이터 삭제
모든 데이터를 지워야 한다는 단점, 연관관계가 있는 경우 비효율적
-
매 테스트 이후 Truncate 쿼리로 모든 테이블 초기화
-
@Sql 어노테이션 사용
Test 상단에
@Sql
어노테이션을 통해 ddl 전달테이블 추가될 때마다 파일을 수정해야한다는 단점
-
EntityManager로 Truncate 쿼리 실행
JPA에서 쿼리를 직접 만들 수 있는 EntityManager를 빈으로 주입받고 모든 테이블 이름을 받아 인수테스트 시 TRUNCATE 쿼리 실행
- 참고: h2 truncate는 restart with 1이 필요
@Component @Profile("test") public class DatabaseCleaner implements InitializingBean { @PersistenceContext private EntityManager entityManager; private List<String> tableNames; @Override public void afterPropertiesSet() { tableNames = entityManager.getMetamodel().getEntities().stream() .map(entry -> entry.getName().toLowerCase(Locale.ROOT)) .collect(Collectors.toList()); } @Transactional public void execute() { entityManager.flush(); entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate(); for (String tableName : tableNames) { entityManager.createNativeQuery("TRUNCATE TABLE " + tableName).executeUpdate(); entityManager.createNativeQuery("ALTER TABLE " + tableName + " ALTER COLUMN id RESTART WITH 1").executeUpdate(); } entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY TRUE ").executeUpdate(); } }
-
-
@DirtiesContext
@DirtiesContext 어노테이션을 이용해 생성된 컨텍스트를 더럽히고 항상 새로운 컨텍스트를 생성하도록 하는 것이다.
시간이 오래 걸린다.