본문 바로가기
TIL & WIL

[TIL] #147. 240207 (Controller 테스트 코드 작성시 발생한 오류와 해결 방법)

by mmm- 2024. 2. 7.

Controller 테스트 코드를 작성하는데 아래와 같은 에러가 발생했다.

java.lang.IllegalStateException: Failed to load ApplicationContext for ...

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'userController' defined in file [...\UserController.class]: 
Unsatisfied dependency expressed through constructor parameter 1: 
No qualifying bean of type '...UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. 
Dependency annotations: {} ...


No qualifying bean of type '....UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. 
Dependency annotations: {} ...

이 외에도 JwtUtil와 관련된 비슷한 에러도 있었는데
 

@MockBean  
private UserRepository userRepository;  
@MockBean  
private JwtUtil jwtUtil;

이와 같이 @MockBean annotation을 사용해 Bean을 등록해줬다. 해당 Bean을 테스트에서 당장 활용하지 않더라도 함께 넣어줘야 한다고 한다.
 

블로그 참고
https://m.blog.naver.com/rodpold/222777034555 

 


 
이와 같은 에러가 발생했다.

jakarta.servlet.ServletException: Request processing failed: 
java.lang.IllegalArgumentException: Name for argument of type 
[java.lang.Long] not specified, and parameter name information not available via reflection. 
Ensure that the compiler uses the '-parameters' flag.

해당 코드에는 @PathVariable 방법으로 userId를 받아오는데 해당 부분에 대한 테스트 코드에 문제가 있는 것 같았다.
 
찾아보니 해당 에러는 파라미터 이름에 대한 정보를 찾지 못해 발생하는 문제라고 한다.
 

@PathVariable(name= "otherUserId") Long otherUserId

이런식으로 UserController 코드를 수정하니까 문제가 해결되긴 했지만, 테스트 코드에서 해결할 수 있는 방법은 없을지 궁금했다. 그리고 이름이 같은데 왜 인식을 하지 못하는지에 대해서 의문을 갖게 되었다.
 
찾아본 결과, 앞서 말한 방법 외에도 build.gradle에 아래의 코드를 추가해주거나

compileJava {
	options.compilerArgs<< '-parameters'
}

 
File > Settings > Build, Execution, Deployment > Compiler > Java Compiler 에서 Additional command line parameters 항목에 '-parameters' 옵션을 추가해 설정해주면 된다고 한다.


 
-parameters 옵션은 Java 8부터 도입된 컴파일러 옵션으로, 이를 통해 메서드 매개변수의 이름을 .class 파일에 보존하게 할 수 있다.

Java 컴파일러는 컴파일 과정에서 메모리를 절약하기 위해 메서드 매개변수의 이름 정보를 제거하는데, 이름을 알아야 올바른 데이터를 넣어줄 수 있어 위와 같은 에러가 발생하지 않는다.
 
컴파일러에게 .class 파일에 매개변수명을 보존하도록 지시하여 이러한 문제를 해결하기 위해 build.gradle이나 intelliJ settings에서 설정을 해줘야 한다. 그렇게 해야 스프링이 매개변수명을 알아내고, 그에 맞는 데이터를 바인딩할 수 있다.
 

블로그 참고
https://hianna.tistory.com/833 
https://yeonyeon.tistory.com/184