Как поместить multipart / form-data с помощью Spring MockMvc?

у меня есть метод контроллера с PUT метод, который получает multipart / form-data:

   @RequestMapping(value = "/putIn", method = RequestMethod.PUT)
   public Foo updateFoo(HttpServletRequest request,
                           @RequestBody Foo foo,
                           @RequestParam("foo_icon") MultipartFile file) {
    ...
   }

и я хочу проверить его с помощью MockMvc. К сожалению MockMvcRequestBuilders.fileUpload создает, по сути, экземпляр MockMultipartHttpServletRequestBuilder имеющего POST способ:

super(HttpMethod.POST, urlTemplate, urlVariables)

EDIT: конечно, я могу я не могу создать свою собственную реализацию MockHttpServletRequestBuilder, сказал

public MockPutMultipartHttpServletRequestBuilder(String urlTemplate, Object... urlVariables) {
    super(HttpMethod.PUT, urlTemplate, urlVariables);
    super.contentType(MediaType.MULTIPART_FORM_DATA);
}

, потому что MockHttpServletRequestBuilder пакета-местные конструктор.

но мне интересно, что это более удобно есть ли способ сделать это, может быть, я пропустил некоторые существующий класс или метод для этого?

2 ответов


Да, есть способ,и это тоже просто!

Я сам столкнулся с той же проблемой. Хотя я был обескуражен ответом Сэма Браннена, похоже, что Spring MVC в настоящее время поддерживает загрузку файлов PUT, поскольку я мог бы просто сделать такой запрос с помощью Postman (я использую Spring Boot 1.4.2). Итак, я продолжал копать и обнаружил, что единственная проблема заключается в том, что MockMultipartHttpServletRequestBuilder возвращено MockMvcRequestBuilders.fileUpload() имеет метод hardcoded для "POST". Затем я обнаружил with() метод...

и что позволило мне придумать этот аккуратный маленький трюк, чтобы заставить MockMultipartHttpServletRequestBuilder использовать метод put в любом случае:

    MockMultipartFile file = new MockMultipartFile("data", "dummy.csv",
            "text/plain", "Some dataset...".getBytes());

    MockMultipartHttpServletRequestBuilder builder =
            MockMvcRequestBuilders.fileUpload("/test1/datasets/set1");
    builder.with(new RequestPostProcessor() {
        @Override
        public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
            request.setMethod("PUT");
            return request;
        }
    });
    mvc.perform(builder
            .file(file))
            .andExpect(status().ok());

работает как шарм!


это, к сожалению, в настоящее время не поддерживается в тесте Spring MVC, и я не вижу другой работы, кроме создания собственного пользовательского MockPutMultipartHttpServletRequestBuilder и копирование-N-вставка кода из стандартной реализации.

для чего это стоит, Spring MVC также не поддерживает PUT запросы на загрузку файлов по умолчанию либо. Составные решатели жестко закодированы, чтобы принять только POST запросы на загрузку файлов -- как для Apache Commons, Так и для стандартного API сервлетов поддержка.

если вы хотите, чтобы весна поддерживала PUT запросы кроме того, не стесняйтесь открыть билет весной Jira проблема трекер.