테스트 롤백용 쿼리를 위해 QueryDSL 활용

초록·2023년 11월 23일
0
post-thumbnail

아 테스트 때문에 프로덕션 코드 건드는 건 좀..

테스트를 작성하다보면 프로덕션 코드에선 쓰이지 않는 코드를 써야할 일이 있습니다. 꽤 찝찝한 기분이 들어 그런 상황은 웬만하면 피하려고 노력합니다.

제가 맞딱드렸던 경우는 테스트 롤백과 관련되어있습니다. 실제 DB에 저장된 걸 확인해야하는 테스트에선 @Transactional을 적용하지 않아, 테스트 코드에서 저장된 엔티티를 지우는 rollback 과정이 필요했습니다. h2같은 인메모리 테스트 DB를 쓰면 지울 필요가 없겠지만, 실제 DB로도 테스트 하게 될 수도 있을 것 같아서 rollback 로직을 구현했습니다. 이 때 테스트 데이터 삭제를 위해 특정 데이터를 삭제하는 JPA 메서드를 새로 만든다면, 테스트 코드가 프로덕션 코드에 영향을 주는 셈인데 이런 방향은 지양해야 된다고 생각했습니다.

QueryDSL로 해결!

테스트에 필요한 쿼리를 JPA 메서드로 작성하는 대신 QueryDSL로 구현함으로써 테스트코드가 프로덕션코드에 많은 영향을 주는 것을 방지했습니다.

테스트 메서드 내에서 queryDSL로 delete/update 쿼리를 보내려니 @Transactional로 꼭 감싸줘야한다고 오류가 발생했는데, Self-Invocation 때문에 외부 클래스에 rollback 메서드를 정의해놓고 테스트 메서드에서 호출하도록 했습니다.

테스트 클래스 바깥에 선언된 querydsl rollback 메서드

    @Transactional(readOnly = false)
    public void rollback(){
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();

        transaction.begin();
        jpaQueryFactory
                .delete(QWeatherInfo.weatherInfo)
                .where(QWeatherInfo.weatherInfo.value.gt(99900))
                .execute();
        transaction.commit();
    }

테스트 메서드에서 호출된 querydsl 메서드

    @AfterEach
    private void rollback(){
        rollback.rollback();
    }

롤백(delete) 외에도 Production 코드에선 필요하지 않는 조건으로 조회(select)를 하는 등, 테스트에서 요긴하게 사용했습니다.

느낀 점

QueryDsl을 처음 사용해보면서 기본적인 사용방법에 대해 배울 수 있었습니다.

profile
몰입하고 성장하는 삶을 동경합니다

0개의 댓글