문제 상황
기존 코드는 @SpringBootTest를 사용하였습니다. 테스트를 진행할 때 Intellij의 test를 실행하면 정상 작동되고 gradle clean test를 사용하면 빌드 오류가 났습니다.
즉, 테스트 & 개발할땐 전혀 문제가 없는데 빌드만 하면 저기가 실패합니다.
@SpringBootTest를 사용하면 @Configuration, @Component 등과 같은 주석을 사용하여 빈과 해당 종속성을 정의하여 Spring이 이러한 개체의 인스턴스화, 연결 및 수명 주기 관리를 처리할 수 있도록 합니다.
// 오류 코드
Could not detect default configuration classes for test class [com.ll.MOIZA.boundedContext.selectedTime.service.SelectedTimeServiceFindOverlappingTest]: SelectedTimeServiceFindOverlappingTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
Found @SpringBootConfiguration com.ll.MOIZA.MoizaApplication for test class com.ll.MOIZA.boundedContext.selectedTime.service.SelectedTimeServiceFindOverlappingTest
하지만, 테스트 클래스에서 기본 구성 클래스를 감자할 수 없어서 나타나는 오류를 확인할 수 있습니다.
1차 원인
테스트 파일이 패키지 하위에 존재하지 않아서 @SpringBootApplication을 찾지 못하는 것이다.
1차 해결
// 기존 코드 @SpringBootTest
@SpringBootTest(classes = MoizaApplication.class)
아직 끝나지 않은 문제 상황
404 NOT_FOUND "모임을 찾을 수 없습니다."
org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND "모임을 찾을 수 없습니다."
at app//com.ll.MOIZA.boundedContext.room.service.RoomService.lambda$getRoom$0(RoomService.java:101)
at java.base@17.0.6/java.util.Optional.orElseThrow(Optional.java:403)
at app//com.ll.MOIZA.boundedContext.room.service.RoomService.getRoom(RoomService.java:101)
at java.base@17.0.6/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base@17.0.6/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base@17.0.6/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base@17.0.6/java.lang.reflect.Method.invoke(Method.java:568)
at app//org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
NotProd(테스트용 데이터)를 가져와야 하는데 가져오지 못하고 있습니다.
@Configuration
@Profile({"test", "dev"})
public class NotProd {
@Bean
CommandLineRunner commandLineRunner(
RoomService roomService
) {
return args -> {
Room room = roomService.createRoom(
member1,
"테스트1",
"테스트룸임",
LocalDate.now().plusDays(5),
LocalDate.now().plusDays(7),
LocalTime.of(0, 0),
LocalTime.of(23, 0),
LocalTime.of(3, 0),
LocalDateTime.now().plusDays(2));
...
}
}
}
@SpringBootTest(classes = MoizaApplication.class)
@ActiveProfiles("test")
@Transactional
public class SelectedTimeServiceQueryTest {
...
@BeforeEach
void init() {
member1 = memberService.findByName("user1");
room = roomService.getRoom(1L);
}
@DisplayName("조회_선택_날짜")
@Test
void select_selected_time_by_day() {
assertThat(selectedTimeService.findSelectedTimeByRoomAndDate(
room, LocalDate.now().plusDays(6)).size()).isEqualTo(6);
}
}
기존 코드에서 NotProd와 연결된 값이 명시적으로 지정되지 않았습니다.
이유는 NotProd와 SelectedTimeServiceQueryTest는 다른 패키지에 존재합니다. 그래서 application context에 자동으로 포함되지 않았습니다.
테스트 중 NotProd 구성 클래스를 포함하기위해 @Import를 사용합니다. @Import를 사용하면 이러한 테스트별 구성 클래스를 가져와서 테스트 중에 애플리케이션 컨텍스트에 포함되도록 할 수 있습니다.
@SpringBootTest(classes = MoizaApplication.class)
@ActiveProfiles("test")
@Transactional
@Import(NotProd.class)
public class SelectedTimeServiceQueryTest {
...
@BeforeEach
void init() {
member1 = memberService.findByName("user1");
room = roomService.getRoom(1L);
}
@DisplayName("조회_선택_날짜")
@Test
void select_selected_time_by_day() {
assertThat(selectedTimeService.findSelectedTimeByRoomAndDate(
room, LocalDate.now().plusDays(6)).size()).isEqualTo(6);
}
}
이제 정상적으로 작동합니다. :)
이번 문제의 근본적인 원인 및 해결 방법
Intellij의 test를 실행하면 정상 작동되고 gradle clean test를 사용하면 빌드 오류가 왜 발생하는 이유는 IntelliJ와 Gradle이 클래스 경로 및 테스트 구성을 처리하는 방식이 다르기 때문입니다.
IntelliJ에는 테스트를 성공적으로 실행하는 데 필요한 클래스와 종속성이 자동으로 포함될 수 있는 자체 테스트 러너 및 클래스 경로 관리 기능이 있습니다. 패키지 스캔 또는 기타 구성 설정을 기반으로 NotProd 구성 클래스를 감지할 수 있습니다.
반면에 Gradle은 build.gradle과 같이 빌드 파일에 지정된 구성에 의존합니다. IntelliJ에 비해 테스트 실행 및 클래스 경로 관리에 대한 기본 설정이 다를 수 있습니다.
이 문제를 해결하고 IntelliJ와 Gradle 간에 일관된 동작을 보장하려면 앞서 언급한 대로 테스트 클래스에서 @Import를 사용하여 NotProd 구성 클래스를 명시적으로 지정하면 됩니다.
'Spring > Spring Boot' 카테고리의 다른 글
[SpringBoot] @SpringBootTest와 @Import (0) | 2023.06.28 |
---|---|
[Spring Boot] Spring Boot 3.x 실행 안될 경우 (0) | 2023.04.24 |
DB 연동 에러 HikariPool-1 - Exception during pool initialization (0) | 2022.11.30 |
스프링부트 몽고DB find*() query에러 (0) | 2022.11.25 |
spring-boot, react, axios 사용시 Cors, session, cookie 문제 (0) | 2022.03.04 |
댓글