MockMvc WebAppConfiguration: загрузка отображений сервлета в web.xml
Я пишу интеграционные тесты, используя MockMvc, и мне интересно, есть ли способ загрузить отображения сервлетов из web.xml (который обычно не должен иметь значения).
У меня есть обычай HandlerInteceptor
который соответствует URI запроса (от HttpServletRequest
) против шаблона (используя AntPathMatcher
).
В web.xml я определяю сопоставления сервлетов следующим образом (с соответствующим mobile-context.xml):
<servlet-mapping>
<servlet-name>mobileServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
Поэтому, когда контроллер определяет отображение как "/operation"
запросы должны быть действительно "/services/operation"
, Мой обычай HandlerInterceptor
сопоставляет запросы URI с шаблоном, например "/**/services/{operationName}/**"
,
Мое приложение отлично работает на Tomcat. Однако в @ContextConfiguration я могу указать только mobile-context.xml, поскольку web.xml не является файлом конфигурации Spring. Таким образом, MockMvc позволяет мне только делать запросы "/operation"
и не "/services/operation"
в результате чего мой HandlerInterceptor
бросить исключение.
Есть ли способ заставить MockMvc регистрировать сопоставления сервлетов, или есть какие-нибудь хитрые способы обойти это? Заранее спасибо.
Изменить: аналогичный вопрос здесь предполагает, что то, что мне нужно, невозможно, но у меня нет разрешения изменять исходный код, поэтому я не могу изменить шаблон или HandlerInterceptor
,
2 ответа
Нет способа загрузить сопоставления web.xml. Однако вы можете явно указать контекстный путь, путь сервлета и информацию о пути в запросе. Посмотрите Javadoc для тех методов в MockHttpServletRequestBuilder.
Я использую MockMvc и MockMvcHtmlUnitDriver для тестирования потока навигации в моем приложении. Я столкнулся с проблемой, что MockMvc не может загрузить мои ресурсы javascript, потому что мое отображение сервлета было
<url-pattern>/ui/*</url-pattern>
Поскольку мои навигационные потоки были серией постов и запросов, я не мог просто установить defaultRequest на MockMvcBuilder. Я решил свою проблему, создав MockMvcConfigurer:
public class ServletPathConfigurer implements MockMvcConfigurer {
private final String urlPattern;
private final String replacement;
public ServletPathConfigurer(String urlPattern, String replacement) {
super();
this.urlPattern = urlPattern;
this.replacement = replacement;
}
@Override
public RequestPostProcessor beforeMockMvcCreated(
ConfigurableMockMvcBuilder<?> builder,
WebApplicationContext context) {
return new RequestPostProcessor(){
@Override
public MockHttpServletRequest postProcessRequest(
MockHttpServletRequest request) {
request.setRequestURI(StringUtils.replace(request.getRequestURI(), urlPattern, replacement, 1));
request.setServletPath(StringUtils.replace(request.getServletPath(), urlPattern, replacement, 1));
return request;
}
};
}
а затем добавить его в каждый из моих интеграционных тестов:
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(new ServletPathConfigurer("/ui",""))
.alwaysDo(print())
.build();