-
Execution failed for task ':test' 해결방법Spring boot 2023. 6. 19. 17:39
들어가기 전에
QueryDSL 을 사용하기 위해 환경을 구성하던 중 만나게 된 Execution failed for task ':test'. 관련 오류에 관한 기록이다.
콘솔에 찍힌 오류
contextLoads() FAILED java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:142 Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1770 Caused by: org.hibernate.AnnotationException at CollectionBinder.java:1568
출력된 오류를 검색해본 결과 가장 간단한 방법은 Test 폴더에 작성된 @SpringBootTest 어노테이션을 주석 처리하거나 Test 폴더를 삭제하는 것이다.
build.gradle.kts 파일의 작성된 Test 작업관련 구성을 삭제하는 것도 가능하다.
tasks.withType<Test> { useJUnitPlatform() }
그런데, 삭제하는걸로 마무리하면 테스트 코드를 사용할 수가 없으니 테스트 코드를 작성 가능한 환경으로 구성하고 싶어졌다.
초기 프로젝트가 아닌 이상 다양한 도메인 객체들이 연관되어 코드 작성이 되어 있을 것이다.
도메인 객체들 `mappedBy` 요소가 빠짐없이 작성되어 있어야 내가 테스트하고자 하는 객체를 확인해볼 수 있다.
구현할 테스트 코드
@SpringBootTest @Transactional class NativeBackendApplicationTests { @PersistenceContext EntityManager entityManager; // 스프링데이터 jpa에서 자동 빈 주입 , @Autowired 사용시 빈등록 코드를 별도로 직접 작성하여 주입해야한다. @Test void contextLoads() { Hello hello = new Hello(); entityManager.persist(hello); JPAQueryFactory query = new JPAQueryFactory(entityManager); QHello qHello = new QHello("hello"); Hello result = query .selectFrom(qHello) .fetchOne(); Assertions.assertThat(result).isEqualTo(hello); //Querydsl Q타입이 정상 동작하는가? Assertions.assertThat(result.getId()).isEqualTo(hello.getId());//롬복 @Getter확인 } }
Hello 도메인 객체를 테스트 하기 위해 내가 연결해놓은 데이터베이스의 Hello 테이블이 존재해야 한다.
spring.jpa.hibernate.ddl-auto: none 으로 설정되어 있기 때문이다. 만약 create or create-drop 으로 작성되어 있으면 굳이 Hello 테이블이 존재하지 않아도 되지만 기존 테이블 구조를 유지하면서 테스트 하기 위해서는 none 값으로 구성해야한다.
Hello 도메인 객체에 @Getter 를 선언해 필드값을 가져올 수 있게 구성한다.
@Entity @Getter @Setter(AccessLevel.PRIVATE) @AllArgsConstructor public class Hello { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; protected Hello(){} }
또한, JPA 는 쿼리문을 수행할 때 트랜잭션 안에서 동작해야되기 때문에 @Transactional 어노테이션을 사용한다.
위에서 제시한 내용을 모두 지키고 테스트 코드를 실행하게 되면 성공할 것이다.
오후 5:05:41: Executing 'build'... > Task :compileJava > Task :processResources > Task :classes > Task :resolveMainClassName > Task :bootJar > Task :jar > Task :assemble > Task :compileTestJava > Task :processTestResources NO-SOURCE > Task :testClasses > Task :test OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended 2023-06-19T17:05:59.818+09:00 INFO 14904 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2023-06-19T17:05:59.821+09:00 INFO 14904 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2023-06-19T17:05:59.865+09:00 INFO 14904 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. > Task :check > Task :build BUILD SUCCESSFUL in 18s 7 actionable tasks: 7 executed 오후 5:06:00: Execution finished 'build'.
Tip.
내가 수행한 쿼리문을 실제 데이터베이스 테이블에 접속해 확인해도 데이터가 들어가있지 않다.
왜냐하면, 테스트 코드에서 트랜잭션을 수행하게 되었을 때 rollback 명령이 기본값으로 잡혀있기 때문이다.
기본값으로 rollback 이 잡혀있지 않게되면 테스트코드로 수행하는 쿼리 명령이 데이터베이스의 반영되어 데이터가 변경되기 때문에 rollback 이 기본값으로 잡혀있는 것이다.이렇게 해서 Execution failed for task ':test' 오류를 해결해 테스트 관련 파일과 의존성을 삭제하지 않고도 정상 build 하게 환경구성을 할 수 있다.
'Spring boot' 카테고리의 다른 글
Spring MVC controller 레이어 테스트 결과가 null이 나온다고? (0) 2024.08.30 can not find symbol과 not acceptable (0) 2023.12.04 Spring Boot 와 QueryDSL + Gradle 구성 - ② (0) 2023.06.21 Spring Boot 와 QueryDSL + Gradle 구성 - ① (0) 2023.06.19 spring boot Gradle 에 Querydsl 설정 (0) 2021.11.09