ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @TestConfiguration 설정하기
    프로젝트/미디어 스트리밍 서버 프로젝트 2022. 10. 5. 00:01
    728x90

    개요

    인터셉터를 설정하던 도중에 secretKey를 관리해야 해서 application.properties에서 주입받아서 사용하려고 했습니다.

    @Configuration("WebConfig")
    class WebConfig : WebMvcConfigurer {
        @Value("\${interceptor.secretKey}")
        lateinit var secretKey: String
        override fun addInterceptors(registry: InterceptorRegistry) {
            registry.addInterceptor(AdminInterceptor(secretKey))
                .addPathPatterns("/admin/**/")
        }
    }

     

     

    class AdminInterceptor(var secretKey: String) : HandlerInterceptor {
        override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
            if (request.getHeader("secretKey") == secretKey) {
                return true
            }
            println(request.getHeader("secretKey"))
            println(secretKey)
            throw CustomException(CustomExceptionCode.AUTHORIZATION_ERROR)
        }
    }

     

    이때 @WebMvcTest로 컨트롤러 테스트를 하려고 하면  secretKey에 실제로 값이 제대로 주입되지 않는 현상이 발생합니다.

     

    secretKey를 실제로 출력해보면 다음과 같은 값이 그대로 출력됩니다.${interceptor.secretKey}

     

    해결법은 2가지가 있습니다.

     

    가장 간단한 방법

    test/resources/application.properties에 설정 추가하기

    interceptor.secretKey=yourKey

     

    하지만 application.properties를 github등에서 관리하지 않는 경우가 있습니다.

     

    이런 경우에 application.properties에서 값을 주입받을 수 없기 때문에 테스트에 통과할 수 없게 되고 github action등에 실패할 수 있습니다.

     

    실제로 비어 있는 @SpringBootTest를 실행하게 되면 다음과 같은 에러를 볼 수 있습니다.

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'WebConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'interceptor.secretKey' in value "${interceptor.secretKey}"

     

    이런 경우는 @TestConfiguration을 통해 해결해야 합니다.

     

     

    @TestConfiguration 활용하는 방법

    @TestConfiguration("WebConfig")
    class TestConfig : WebMvcConfigurer {
    
        val secretKey = "yourKey"
    
        @Bean
        fun adminInterceptor() : AdminInterceptor{
            return AdminInterceptor(secretKey)
        }
    
        override fun addInterceptors(registry: InterceptorRegistry) {
            registry.addInterceptor(AdminInterceptor(secretKey))
                .addPathPatterns("/admin/**/")
        }
    }

    WebConfig를 만든것처럼 동일하게 @TestConfiguration을 등록합니다.

     

    또한 테스트하는 컨트롤러에 다음과 같은 어노테이션을 추가해줍니다.

    @SpringBootTest
    @Import(TestConfig::class)
    class VideoApplicationTests {
    
        @Test
        fun contextLoads() {
        }
    }

     

    이제 다시 테스트를 실행하면 다음과 같은 에러가 나옵니다.

    ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    The bean 'WebConfig' could not be registered. A bean with that name has already been defined in file [경로] and overriding is disabled.
    
    Action:
    
    Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

     

    맨 밑을 읽어보면 다음과 같은 세팅을 하라는 것을 고려해보라고 합니다.

    spring.main.allow-bean-definition-overriding=true

     

    이제 테스트가 정상적으로 잘 동작합니다.

     

     

    댓글

Designed by Tistory.