[SPRING] JUnitTest의 @ControllerAdvice 주석이 달린 컨트롤러를 MockMVC에 등록하십시오.
SPRINGJUnitTest의 @ControllerAdvice 주석이 달린 컨트롤러를 MockMVC에 등록하십시오.
내 @ControllerAdvice 주석이 달린 컨트롤러는 다음과 같습니다.
@ControllerAdvice
public class GlobalControllerExceptionHandler {
@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
@ExceptionHandler(AuthenticationException.class)
public void authenticationExceptionHandler() {
}
}
물론 내 개발은 테스트 중심이며 JUnit 테스트에서 예외 처리기를 사용하고 싶습니다. 내 테스트 케이스는 다음과 같습니다.
public class ClientQueriesControllerTest {
private MockMvc mockMvc;
@InjectMocks
private ClientQueriesController controller;
@Mock
private AuthenticationService authenticationService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void findAllAccountRelatedClientsUnauthorized() throws Exception {
when(authenticationService.validateAuthorization(anyString())).thenThrow(AuthenticationException.class);
mockMvc.perform(get("/rest/clients").header("Authorization", UUID.randomUUID().toString()))
.andExpect(status().isUnauthorized());
}
}
아마도 ControllerAdvice 클래스를 등록해야합니다. 그렇게하는 방법?
해결법
-
==============================
1.Spring 4.2부터 ControllerAdvice를 직접 StandaloneMockMvcBuilder에 등록 할 수 있습니다 :
Spring 4.2부터 ControllerAdvice를 직접 StandaloneMockMvcBuilder에 등록 할 수 있습니다 :
MockMvcBuilders .standaloneSetup(myController) .setControllerAdvice(new MyontrollerAdvice()) .build();
-
==============================
2.전체 Spring MVC 설정을 활성화하려면 MockMvcBuilders.standaloneSetup 대신 MockMvcBuilders.webAppContextSetup을 사용해야합니다.
전체 Spring MVC 설정을 활성화하려면 MockMvcBuilders.standaloneSetup 대신 MockMvcBuilders.webAppContextSetup을 사용해야합니다.
자세한 것은 Spring 문서의이 부분을 확인하십시오.
코드는 다음과 같습니다.
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration("test-config.xml") public class ClientQueriesControllerTest { private MockMvc mockMvc; @Autowired private WebApplicationContext webApplicationContext; @Autowired private AuthenticationService authenticationService; @Before public void setup() { MockitoAnnotations.initMocks(this); mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } @Test public void findAllAccountRelatedClientsUnauthorized() throws Exception { when(authenticationService.validateAuthorization(anyString())).thenThrow(AuthenticationException.class); mockMvc.perform(get("/rest/clients").header("Authorization", UUID.randomUUID().toString())) .andExpect(status().isUnauthorized()); } }
그런 다음 test-config.xml 내에서 모의 인 AuthenticationService 용 Spring bean을 추가한다.
<bean id="authenticationService" class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="your.package.structure.AuthenticationService"/> </bean>
test-config.xml을 만드는 대신 일반 Spring 구성 파일을 다시 사용하려면 모의 AuthenticationService를 테스트에 삽입하는 데 프로필을 사용할 수 있습니다.
최신 정보
조금 뒤져서, (MockMvcBuilders.standaloneSetup)에 의해 반환 된 StandaloneMockMvcBuilder가 완전히 사용자 정의 가능하다는 것을 알았습니다. 즉, 사용자가 선호하는 예외 해석자를 플러그인 할 수 있습니다.
그러나 @ControllerAdvice를 사용하고 있기 때문에 아래 코드는 작동하지 않습니다. 그러나 @ExceptionHandler 메서드가 동일한 컨트롤러 안에 있으면 코드를 모두 변경해야합니다.
mockMvc = MockMvcBuilders.standaloneSetup(controller).setHandlerExceptionResolvers(new ExceptionHandlerExceptionResolver()).build();
업데이트 2
@ControllerAdvice를 사용할 때 정확한 예외 핸들러를 등록 할 수있는 방법에 대한 답을 얻습니다.
테스트의 설정 코드를 다음과 같이 업데이트해야합니다.
@Before public void setUp() throws Exception { final ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver = new ExceptionHandlerExceptionResolver(); //here we need to setup a dummy application context that only registers the GlobalControllerExceptionHandler final StaticApplicationContext applicationContext = new StaticApplicationContext(); applicationContext.registerBeanDefinition("advice", new RootBeanDefinition(GlobalControllerExceptionHandler.class, null, null)); //set the application context of the resolver to the dummy application context we just created exceptionHandlerExceptionResolver.setApplicationContext(applicationContext); //needed in order to force the exception resolver to update it's internal caches exceptionHandlerExceptionResolver.afterPropertiesSet(); mockMvc = MockMvcBuilders.standaloneSetup(controller).setHandlerExceptionResolvers(exceptionHandlerExceptionResolver).build(); }
-
==============================
3.다음 해결책으로 NestedServletException을 지나쳤습니다 ...
다음 해결책으로 NestedServletException을 지나쳤습니다 ...
final StaticApplicationContext applicationContext = new StaticApplicationContext(); applicationContext.registerSingleton("exceptionHandler", GlobalControllerExceptionHandler.class); final WebMvcConfigurationSupport webMvcConfigurationSupport = new WebMvcConfigurationSupport(); webMvcConfigurationSupport.setApplicationContext(applicationContext); mockMvc = MockMvcBuilders.standaloneSetup(controller). setHandlerExceptionResolvers(webMvcConfigurationSupport.handlerExceptionResolver()). build();
-
==============================
4.이것을 테스트 클래스에 추가 할 수 있습니다.
이것을 테스트 클래스에 추가 할 수 있습니다.
@Autowired @Qualifier("handlerExceptionResolver") void setExceptionResolver(HandlerExceptionResolver resolver) { this.exceptionResolver = resolver; }
MockMvc에 exceptionResolver를 추가하십시오.
@Before public void setup() { MockitoAnnotations.initMocks(this); mockMvc = MockMvcBuilders.standaloneSetup(controller) .setHandlerExceptionResolvers(this.exceptionResolver).build(); }
from https://stackoverflow.com/questions/25604215/register-controlleradvice-annotated-controller-in-junittest-with-mockmvc by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] RestTemplate은 URL을 이스케이프 처리하지 않습니다. (0) | 2019.03.24 |
---|---|
[SPRING] 스프링 컨테이너가 빈의 싱글 톤 인스턴스를 반환하지 않게하려면 어떻게해야합니까? (0) | 2019.03.24 |
[SPRING] 'hibernate.dialect'가 설정되어 있지 않으면 Connection은 null이 될 수 없다. (0) | 2019.03.24 |
[SPRING] Spring Boot에서 다중 데이터 소스와 스키마 생성 (0) | 2019.03.24 |
[SPRING] 다른 패키지의 @RestController가 작동하지 않습니다. (0) | 2019.03.24 |