때는 바야흐로..
ATDD 과정 수강 중 각각의 E2E 인수테스트의 데이터베이스를 서로 영향받지않게 격리 시켜주기 위해
test 패키지에 만든 별도의 클래스를 빈으로 올려 @Autowired 로 주입받고자 했습니다.
하지만 에러가 뜨는군요!
DataBaseCleanUp 이라는 Class는 Test 패키지 아래에서만 존재하는 클래스입니다.
@TestComponent
public class DataBaseCleanUp {
.. 생략
}
- @SpringBootConfiguration 의 scan 대상으로는 포함시키지 않기위해 @TestComponent 를 적용해 주었습니다.
- @TestComponent는 Test 를 위한 Component 이지만, javadoc 설명처럼 직접적으로 ComponentScan 을 사용하는 경우 Filter 에 대한 정의를 해주어야하는 유의사항이 있습니다.
📌error code
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
@SpringBootTest 빈 컨텍스트 등록 과정
@SpringBootTest 어노테이션은 @SpringBootApplication이 있는 Application 을 찾아서 사용하고,
그렇게 찾은 @SpringBootApplication 안의 @ComponentScan이 스캔한 빈들을 그대로 스프링 컨텍스트에 올려서 사용한다고 하더군요
그리고 테스트에서 실행했기 때문에 test 중에서도 hello.core를 포함한 그 하위 패키지는 컴포넌트 스캔의 대상이 된다고 합니다,,,
에러 해결 방법
📌 지금 깨달아서 해본건데 test 패키지 안에서도 '@SpringBootApplication이 있는 Application' 패키지 내부에 존재하는 컴포넌트들은 스캔의 대상이 됩니다..
따라서 패키지 구조를 잘 맞춰주면 됩니다.
📌 하지만 저 처럼 우매한 실수를 하거나 고집이 쎄서 맞추기 싫다! 하신다면 @ContextConfiguration 를 사용하시면 됩니다.
이런 구조였고 아래처럼, 컨택스트를 포함해줄 클래스에 추가해주었습니다.
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@ContextConfiguration(classes= {DataBaseCleanUp.class, SubwayApplication.class})
public abstract class AcceptanceTestConfig {
@Autowired
DataBaseCleanUp dataBaseCleanUp;
@BeforeEach
void setUp() {
dataBaseCleanUp.clean();
}
}
결론.
테스트도 패키지 구조를 잘 맞추고
원리를 이해하고 코딩하자.. ㅠ