Test

WebMvcTest 에러

잔망루피 2023. 3. 8. 19:32

WebMvcTest 어노테이션을 사용해서 컨트롤러를 테스트하는 코드를 작성하면서 발생한 문제에 대해 정리했다.

 


 

1. jpaAuditingHandler 빈 생성 에러

// 에러로그
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaAuditingHandler': Cannot resolve reference to bean 'jpaMappingContext' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: JPA metamodel must not be empty!
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: JPA metamodel must not be empty!
Caused by: java.lang.IllegalArgumentException: JPA metamodel must not be empty!

 

[첫 번째 방법: @AutoConfigurerDataJpa 어노테이션을 추가]

나는 auditing을 사용하고 있어서 @AutoConfigurerDataJpa 어노테이션을 추가하면 된다.

@AutoConfigurerDataJpa는 일반적인 Data JPA 테스트를 위한 Auto-configuration을 import한다.

 

 

[두 번째 방법: @DataJpaTest 어노테이션을 추가]

// 에러로그
Test ignored.

java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [com.membershipservice.controller.UserControllerTest]: [@org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestContextBootstrapper.class), @org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper.class)]

@DataJpaTest를 사용하는 방법

대부분의 테스트는 @DataJpaTest를 사용하는 것을 권장한다고 해서 했더니 위와 같은 에러가 뜬다.

@DataJpaTest는 JPA 컴포넌트에만 집중한다.

이 어노테이션을 사용하면 full auto-configuration이 안 된다.

JPA 테스트와 관련된 설정만 적용한다.

기본적으로 각 테스트의 마지막에 트랜잭션, roll back을 한다.

또한 내장된 in-memory database를 사용한다.

난 컨트롤러만 테스트하니까 JPA를 직접적으로 사용하지 않으므로 이 어노테이션이 필요없다.

 

 


 

2. Security 문제

WebMvcTest에서 Security를 사용하지 않고 싶었다.

@WebMvcTest(controllers = UserController.class,
        excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JwtRequestFilter.class, WebSecurityConfigurerAdapter.class})
})
@AutoConfigureDataJpa
@AutoConfigureMockMvc(addFilters = false)

Filter도 스캔하니까 내가 작성한 JwtRequestFilter를 exclude했다.

addFilters = false로 Spring Security filters를 없앴다.

@AutoConfigureMockMvc 어노테이션은 MockMvc의 auto-configuration을 설정한다.

 

 


 

👇👇👇 아래는 시도했지만 실패했던 3가지 방법들

1. excludeFilters로 제외시킨다.

@WebMvcTest(controllers = UserController.class,
        excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JwtRequestFilter.class})
})
@AutoConfigureDataJpa

이렇게 하면 메소드에 @WithMockUser 어노테이션을 붙여야 함

만약에 로그인 컨트롤러를 테스트한다고 했을 때 특히 더 이상하다.

 

 

2. 내가 작성한 SecurityConfig 클래스를 import해서 URL에서 따라서 인증을 적용할려고 함

@WebMvcTest(controllers = UserController.class,
        excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JwtRequestFilter.class})
})
@AutoConfigureDataJpa
@Import(SecurityConfig.class)
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.membershipservice.conifg.SecurityConfig': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.membershipservice.conifg.CustomAuthenticationEntryPoint' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.membershipservice.conifg.SecurityConfig': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.membershipservice.conifg.CustomAuthenticationEntryPoint' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.membershipservice.conifg.CustomAuthenticationEntryPoint' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

테스트가 복잡해진다...

 

 

3. WebSecurityConfigurerAdapter 클래스를 exclude

@WebMvcTest(controllers = UserController.class,
        excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JwtRequestFilter.class, WebSecurityConfigurerAdapter.class})
})
@AutoConfigureDataJpa
WebSecurityConfig 는 WebSecurityConfigurerAdater 를 상속하므로 WebSecurityConfgurerAdater 스캔을 제외하면 당연히 WebSecurityConfig 도 스캔되지 않는다.

출처
https://velog.io/@cieroyou/WebMvcTest%EC%99%80-Spring-Security-%ED%95%A8%EA%BB%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0#-%EA%B2%B0%EB%A1%A0

이렇게 해도 security를 제거할 수 없다.

 

 


 

참고 👇

https://www.appsdeveloperblog.com/disable-spring-security-configuration-for-webmvctest/

 

Disable Spring Security Configuration for @WebMvcTest - Apps Developer Blog

In this blog post, you will learn a couple of ways you can disable Spring Security Configuration for your @WebMvcTest. Disable Security Filters for @AutoConfigureMockMvc One of the ways you can disable Spring Security filters in your tests, is to use the @

www.appsdeveloperblog.com

 

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/orm/jpa/AutoConfigureDataJpa.html

 

AutoConfigureDataJpa (Spring Boot 3.0.4 API)

 

docs.spring.io

 

https://www.appsloveworld.com/mongodb/100/19/using-embedded-mongodb-in-spring-junit-webmvctest

 

Using embedded MongoDB in Spring JUnit @WebMvcTest-mongodb

Coding example for the question Using embedded MongoDB in Spring JUnit @WebMvcTest-mongodb

www.appsloveworld.com

 

반응형

'Test' 카테고리의 다른 글

JaCoCo  (0) 2023.04.20