추후 수정될 수 있는 글입니다
h2 Memory DB, mysql mode로 테스트 도중 auto_increment를 테스트 마다 rest을 해줘야 하는 상황이 생겼다.
entityManager.createNativeQuery("ALTER TABLE `item` AUTO_INCREMENT=1").executeUpdate();
java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
jdbcTemplate.execute("ALTER TABLE `item` AUTO_INCREMENT=1");
org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [ALTER TABLE `item` AUTO_INCREMENT=1]
통해 auto_increment Reset 을 수행하려 했으나 오류가 발생하며 실패했다.
열심히 구글링하여 다른 방법을 찾아본 결과
테스트 클래스 위에 다음 어노테이션을 추가하여 해결하였다.
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class OrderIntegrationTest extends BaseIntegrationTest {
@Autowired
ItemJpaRepository itemJpaRepository;
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private JdbcTemplate jdbcTemplate;
@BeforeEach
void beforeAll() {
ItemEntity item1 = EntityCreator.createItemEntity(null, "좋은 상품1", 1000L, 10L);
ItemEntity item2 = EntityCreator.createItemEntity(null, "좋은 상품2", 2000L, 20L);
ItemEntity item3 = EntityCreator.createItemEntity(null, "좋은 상품3", 3000L, 30L);
ItemEntity item4 = EntityCreator.createItemEntity(null, "좋은 상품4", 4000L, 40L);
ItemEntity item5 = EntityCreator.createItemEntity(null, "좋은 상품5", 5000L, 50L);
itemJpaRepository.saveAll(List.of(item1, item2, item3, item4, item5));
}
@AfterEach
void afterEach() throws Exception {
itemJpaRepository.deleteAllInBatch();
}
@Nested
@DisplayName("상품 주문")
class CreateOrder {
...
}
@Nested
@DisplayName("주문 목록 조회")
class GetOrders {
...
}
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class OrderIntegrationTest extends BaseIntegrationTest {
...
@DirtiesContext는 Spring 테스트 주석입니다. 연관된 테스트 또는 클래스가 ApplicationContext를 수정함을 나타냅니다. 테스트 프레임워크에 이후 테스트를 위해 컨텍스트를 닫고 다시 생성하도록 지시합니다. 테스트 메서드나 전체 클래스에 주석을 달 수 있습니다. MethodMode 또는 ClassMode를 설정하면 Spring이 컨텍스트를 닫을 때를 제어할 수 있습니다. 클래스에 @DirtiesContext를 배치하면 해당 ClassMode가 있는 클래스의 모든 메서드에 주석이 적용됩니다.
결과적으로 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)을 통하여 @Nested의 테스트 사이 마다 Spring boot test가 다시 실행되며 최초에 테스트하는 환경을 만들어 주는것