В 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
|
@Testpublic 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.