문제상황
@ActiveProfiles("test")
@SpringBootTest
//@SpringBootTest: 전체 Spring 애플리케이션 컨텍스트를 로드
@AutoConfigureMockMvc
//AutoConfigureMockMvc: MockMvc 인스턴스를 자동 구성하는 데 사용됩니다.
//MockMvc는 Spring MVC 애플리케이션의 컨트롤러를 테스트하기 위한 주요 도구입니다. 이를 사용하여 HTTP 요청을 보내고 응답을 검증할 수 있습니다.
public class ControllerTest {
MockMvc mockMvc;
@BeforeEach
public void setUp(WebApplicationContext applicationContext) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(applicationContext).build();
}
...
}
- 위 코드는 생성자 주입이나 필드주입의 경우가 아닌데도 불구하고 주입이 되어서 테스트가 성공적으로 돌아가고 있었습니다
@SpringBootTest
@AutoConfigureMockMvc
public class ControllerTest {
MockMvc mockMvc;
Repository repository;
@BeforeEach
public void setUp(WebApplicationContext applicationContext, Repository repository) {
this.repository=repository;
this.mockMvc = MockMvcBuilders.webAppContextSetup(applicationContext).build();
}
...
}
- 하지만 Repository코드를 다음과 같이 추가한다고 하면 No ParameterResolver registered for parameter 과 같은 오류가 뜨면서 테스트가 실패하였습니다
- 해당 오류는 일반적으로 JUnit이 처리 방법을 모르는 매개변수가 있는 테스트 클래스의 생성자나 메소드를 사용하려고 할 때 JUnit 5에서 발생합니다.
문제원인
- 공식문서에서는 다음과 같이 정의하고 있습니다
ParameterResolver는 런타임 시 매개변수에 대한 인수를 동적으로 확인하려는 확장용 API를 정의합니다.
테스트 클래스의 생성자 또는 @Test, @BeforeEach, @AfterEach, @BeforeAll 또는 @AfterAll 메서드가 매개 변수를 선언하는 경우 매개 변수에 대한 인수는 런타임 시 ParameterResolver에 의해 확인되어야 합니다.
public interface ParameterResolver extends Extension {
boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException;
Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException;
}
- supportsParameter(ParameterContext, ExtensionContext): 이 메소드는 주어진 ParameterContext와 ExtensionContext에 대해 이 리졸버가 매개변수의 인자를 지원하는지를 결정합니다. 즉, 특정 매개변수를 해결할 수 있는지 여부를 판단합니다.
- resolveParameter(ParameterContext, ExtensionContext): 이 메소드는 supportsParameter 메소드가 true를 반환한 경우에만 프레임워크에 의해 호출됩니다. 매개변수에 대한 인자를 제공하여 반환합니다.
- 또한 JUnit 5에서는 테스트 메소드나 라이프사이클 메소드(예: @BeforeEach)의 매개변수가 Spring처럼 자동으로 주입되지 않습니다. 대신 JUnit 5는 ParameterResolver 구현을 사용하여 매개변수를 확인합니다. 이는 매개변수가 주입되려면 이를 지원하는 해당 ParameterResolver가 있어야 함을 의미합니다.
If a test class constructor, test method, or lifecycle method (see Definitions) declares a parameter, the parameter must be resolved at runtime by a ParameterResolver. A ParameterResolver can either be built-in (see TestInfoParameterResolver) or registered by the user. Generally speaking, parameters may be resolved by name, type, annotation, or any combination thereof.
<번역>
테스트 클래스 생성자, 테스트 메서드 또는 수명 주기 메서드(정의 참조)가 매개 변수를 선언하는 경우 해당 매개 변수는 런타임 시 ParameterResolver에 의해 확인되어야 합니다. ParameterResolver는 내장되어 있거나(TestInfoParameterResolver 참조) 사용자가 등록할 수 있습니다. 일반적으로 매개변수는 이름, 유형, 주석 또는 이들의 조합으로 분석될 수 있습니다.
- 공식문서의 내용을 인용한 내용입니다
- 위의 내용에 따르면, ParameterResolver은 미리 등록된 요소에 한에서만 주입이 되는것으로 보입니다
- 따라서, 기본적으로 일부 잘 알려진 타입(예: WebApplicationContext)에 대해서만 주입을 지원해서 사용자 정의 컴포넌트는 지원되지 않는 것 같습니다.
결론
- @autowired을 쓰면 스프링이 주입을 해주지만, 메서드 매개변수에 대해서는 junit이 ParameterResolver을 사용하여 매개변수를 주입합니다.
- JUnit 5는 기본적으로 일부 잘 알려진 타입(예: WebApplicationContext)에 대해서만 주입을 지원해서 사용자 정의 컴포넌트는 지원되지 않는 것 같습니다.
https://junit.org/junit5/docs/current/user-guide/#extensions-parameter-resolution
'문제해결' 카테고리의 다른 글
| 부팅 시 도커 데몬 자동 실행하게 하기 (0) | 2024.09.09 |
|---|---|
| ProcessBuilder를 활용한 표준 출력 및 로그 파일 관리 (0) | 2023.12.23 |
| Reddisson을 활용한 동시성 문제 해결 (1) | 2023.10.04 |
| 로드밸런싱을 통한 높은 CPU 점유율 해결하기 (0) | 2023.09.18 |
| pinpoint & nGrinder 사용하여 대용량 트래픽 시 오류 확인 (0) | 2023.09.14 |