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();
Другие вопросы по тегам