В Junit4 эта поддержка состоит из пользовательского Runit Junit, называемого SpringJunit4ClassRunner, и пользовательской аннотации для загрузки соответствующей конфигурации Spring.
Пример Интеграционного теста будет выглядеть следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
@RunWith (SpringJUnit4ClassRunner. class ) @ContextConfiguration (locations={ "classpath:/META-INF/spring/webmvc-config.xml" , "contextcontrollertest.xml" }) public class ContextControllerTest { @Autowired private RequestMappingHandlerAdapter handlerAdapter; @Autowired private RequestMappingHandlerMapping handlerMapping; ...... @Test public void testContextController() throws Exception{ MockHttpServletRequest httpRequest = new MockHttpServletRequest( "POST" , "/contexts" ); httpRequest.addParameter( "name" , "context1" ); httpRequest.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); MockHttpServletResponse response = new MockHttpServletResponse(); Authentication authentication = new UsernamePasswordAuthenticationToken( new CustomUserDetails(..), null ); SecurityContextHolder.getContext().setAuthentication(authentication); Object handler = this .handlerMapping.getHandler(httpRequest).getHandler(); ModelAndView modelAndView = handlerAdapter.handle(httpRequest, response, handler); assertThat(modelAndView.getViewName(), is( "redirect:/contexts" )); } } |
Я использовал MockHttpServletRequest для создания фиктивного POST-запроса к URI «/ contexts» и добавил некоторые детали аутентификации для деталей, связанных с Spring Security, которые будут доступны в контроллере. ModelAndView, возвращаемый контроллером, проверяется, чтобы убедиться, что возвращаемое имя представления соответствует ожидаемому.
Лучший способ выполнить интеграцию, связанную с контроллером, — это использование относительно нового проекта Spring под названием Spring-test-mvc , который обеспечивает свободный способ тестирования потоков контроллера. Те же тесты, что и выше, выглядят следующим образом с Spring-test-mvc:
01
02
03
04
05
06
07
08
09
10
|
@Test public void testContextController() throws Exception{ Authentication authentication = new UsernamePasswordAuthenticationToken( new CustomUserDetails(..), null ); SecurityContextHolder.getContext().setAuthentication(authentication); xmlConfigSetup( "classpath:/META-INF/spring/webmvc-config.xml" , "classpath:/org/bk/lmt/web/contextcontrollertest.xml" ).build() .perform(post( "/contexts" ).param( "name" , "context1" )) .andExpect(status().isOk()) .andExpect(view().name( "redirect:/contexts" )); } |
Теперь тест стал намного более кратким, и нет необходимости напрямую иметь дело с экземплярами MockHttpServletRequest и MockHttpServletResponse, и он очень хорошо читает.
У меня есть небольшая оговорка относительно количества статического импорта и количества вызовов функций, которые здесь задействованы, но опять же, как и все остальное, это просто вопрос привыкания к этому подходу тестирования.
Ресурсы в разделе WEB-INF также можно использовать с spring-test-mvc, таким образом:
01
02
03
04
05
06
07
08
09
10
11
|
xmlConfigSetup( "/WEB-INF/spring/webmvc-config.xml" , "classpath:/org/bk/lmt/web/contextcontrollertest.xml" ) .configureWebAppRootDir( "src/main/webapp" , false ).build() .perform(post( "/contexts" ).param( "name" , "context1" )) .andExpect(status().isOk()) .andExpect(view().name( "redirect:/contexts" )); xmlConfigSetup( "/WEB-INF/spring/webmvc-config.xml" , "classpath:/org/bk/lmt/web/contextcontrollertest.xml" ) .configureWebAppRootDir( "src/main/webapp" , false ).build() .perform(get( "/contexts" )) .andExpect(status().isOk()) .andExpect(view().name( "contexts/list" )); |
Ссылка: Spring MVC Integration Tests от нашего партнера JCG Биджу Кунджуммена в блоге all and sundry.