h2 auto_increment rest in test

itbuddy·2024년 9월 28일

꿀팁

목록 보기
10/12

추후 수정될 수 있는 글입니다

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)

auto_increment를 1로 reset 해야하는 대상 코드

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 ?

@DirtiesContext는 Spring 테스트 주석입니다. 연관된 테스트 또는 클래스가 ApplicationContext를 수정함을 나타냅니다. 테스트 프레임워크에 이후 테스트를 위해 컨텍스트를 닫고 다시 생성하도록 지시합니다. 테스트 메서드나 전체 클래스에 주석을 달 수 있습니다. MethodMode 또는 ClassMode를 설정하면 Spring이 컨텍스트를 닫을 때를 제어할 수 있습니다. 클래스에 @DirtiesContext를 배치하면 해당 ClassMode가 있는 클래스의 모든 메서드에 주석이 적용됩니다.

결과적으로 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)을 통하여 @Nested의 테스트 사이 마다 Spring boot test가 다시 실행되며 최초에 테스트하는 환경을 만들어 주는것

Ref

A Quick Guide to @DirtiesContext

profile
프론트도 조금 아는 짱구 같은 서버 프로그래머

0개의 댓글