java - 在JUnitTest中使用 MockMVC,java register @ControllerAdvice 註釋

  显示原文与译文双语对照的内容
146 0

我的@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());


 }


}



可能我需要用 register 。 怎麼做?

时间: 原作者:

122 5

為了讓完整的Spring MVC 配置被激活,你需要使用 MockMvcBuilders.webAppContextSetup 而不是 MockMvcBuilders.standaloneSetup

查看這是文檔的一部分。

你的代碼將如下所示:


@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>



當然,如果希望重用常規 spring 配置文件而不是創建 test-config.xml,那麼你可以使用概要文件在測試中注入模擬 AuthenticationService

更新

我發現了一點,我發現( MockMvcBuilders.standaloneSetup ) 返回的StandaloneMockMvcBuilder 完全可以定製。 這意味著你可以插入任何你喜歡的異常解析器。

但是,由於你使用的是 @ControllerAdvice,下面的代碼將無法工作。 如果你的@ExceptionHandler 方法在相同的控制器內,你所需要更改的代碼就是以下內容:


mockMvc = MockMvcBuilders.standaloneSetup(controller).setHandlerExceptionResolvers(new ExceptionHandlerExceptionResolver()).build();



更新2

一些更多的挖掘給出了如何在使用 @ControllerAdvice 時對正確的異常處理程序進行 register 處理的答案。

你需要將測試中的設置代碼更新為以下內容:


 @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();


 }



原作者:
112 2

從 spring 4.2開始,你可以直接將你的ControllerAdvice register 到你的StandaloneMockMvcBuilder中:


MockMvcBuilders


. standaloneSetup(myController)


. setControllerAdvice(new MyontrollerAdvice())


. build();



136 2

通過以下解決方案通過了 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();



74 0

你可以將這裡添加到你的測試類


@Autowired


@Qualifier("handlerExceptionResolver")


void setExceptionResolver(HandlerExceptionResolver resolver)


{


 this.exceptionResolver = resolver;


}



然後將 exceptionResolver 添加到MockMvc中


@Before


public void setup() {


 MockitoAnnotations.initMocks(this);


 mockMvc = MockMvcBuilders.standaloneSetup(controller)


. setHandlerExceptionResolvers(this.exceptionResolver).build();


}



...