본문 바로가기
  • 개발하는 곰돌이
Development/Errors

[JUnit5] DB호출 테스트 중 발생한 No ParameterResolver registered for parameter in constructor 에러 해결

by 개발하는 곰돌이 2023. 1. 11.

에러 발생 배경

JUnit5로 DB 호출 테스트를 하는 도중에 다음과 같은 에러가 발생했다.

No ParameterResolver registered for parameter [com.settlement.mapper.TestMapper testMapper] in constructor [public com.settlement.controller.TestController(com.settlement.mapper.TestMapper)].
org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [com.settlement.mapper.TestMapper testMapper] in constructor [public com.settlement.controller.TestController(com.settlement.mapper.TestMapper)].

클래스의 생성자에 있는 mapper 파라미터에 대한 ParameterResolver가 존재하지 않는다고 한다. 메인 코드에서는 분명히 동작하는데 테스트 코드에서는 에러가 발생하니 굉장히 당황스러웠다. 구글링을 해본 결과 메인 코드와 테스트 코드에서 의존성을 주입하는 주체가 달라서 발생하는 에러라고 한다.


해결 방법

결론부터 말하자면 생성자를 통한 의존성 주입 방법을 사용하고 있는 경우, 생성자에 @Autowired 어노테이션을 명시해야 한다.

 

기존에는 의존성 주입을 할 때 생성자를 통한 방법을 사용해서 @Autowired 어노테이션을 생략해서 사용하고 있었다. 이 경우 메인 코드에서는 Spring IoC 컨테이너가 의존성 주입을 담당하기 때문에 생성자를 통한 의존성 주입을 할 때 @Autowired 어노테이션을 생략하더라도 스프링 프레임워크가 알아서 잘 처리를 해준다고 한다. 하지만 테스트 코드에서는 Spring 컨테이너가 아니라 JUnit5의 Jupiter가 의존성 주입을 담당하는데 @Autowired가 선언된 객체를 탐색하고 Spring 컨테이너에 요청하여 의존성을 주입하게 된다고 한다. 즉, @SpringBootTest 어노테이션은 Spring Boot와 비슷한 환경을 조성해 주는 것일 뿐이라서 테스트 코드에서 @Autowired가 생략되어 있다면 Jupiter가 객체를 탐색하지 못하기 때문에 예외가 발생하는 것이다.

 

따라서 테스트 코드에서 생성자를 통한 의존성 주입을 할 때는 아래와 같이 선언해주면 된다.

// Kotlin
@SpringBootTest
class TestController @Autowired constructor(
    private val testMapper: TestMapper
) {
    
    ...
    
}
// Java
@SpringBootTest
public class TestController {
    private final TestMapper testMapper;
    
    @Autowired
    public TestController(TestMapper testMapper) {
        this.testMapper = testMapper;
    }
    
    ...
    
}

참조링크

https://minkukjo.github.io/framework/2020/06/28/JUnit-23/

댓글