Skip to main content
 首页 » 编程设计

spring-mvc之如何使用 Spring MVC 和 Spock 使用 PUT 请求进行多部分单元测试

2025年05月04日139落叶无声

我有一个这样的 Controller :

@RestController 
@RequestMapping('/v1/document') 
class DocumentV1Controller { 
  @PutMapping 
  HttpEntity<Document> newdoc( 
    @RequestHeader Map<String, String> headers, @RequestParam('document') MultipartFile multipartFile) { 
  } 
} 

我想使用 Spring MVC Test 和 Spock 来测试它,但我就是不知道如何构建一个 MockMultipartHttpServletRequestBuilder将 HttpMethod 从 POST 更改为 PUT 请求。

这是 Spock 规范:
class DocumentV1ControllerSpec extends BaseControllerSpec { 
  Should 'test and document good request on /v1/document endpoint'() { 
    given: 
      File file = new File('./src/test/resources/demoC.csv') 
      MockMultipartFile multipartFile = new MockMultipartFile('file',file.getBytes()) 
    when: 
      ResultActions result = mockMvc.perform(fileUpload('/v1/document') 
        .file(multipartFile)) 
    then: 
      result.andExpect(status().isCreated()) 
  } 
} 

我得到的错误是这样的:
java.lang.AssertionError: Status expected:<201> but was:<405> 
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60) 
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89) 
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664) 
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171) 
at gus.rest.api.v1.DocumentV1ControllerSpec.test and document good request on /v1/document endpoint(DocumentV1ControllerSpec.groovy:61) 

我该怎么做才能让它发挥作用?

请您参考如下方法:

我不是 spock 的专家,但是方法 fileUpload现在已弃用 Spring(版本 5.*)。

有一种方法可以将 MockMultipartHttpServletRequestBuilder 的默认 POST 方法更改为 PUT:

class DocumentV1ControllerSpec extends BaseControllerSpec { 
  Should 'test and document good request on /v1/document endpoint'() { 
    given: 
      File file = new File('./src/test/resources/demoC.csv') 
      MockMultipartFile multipartFile = new MockMultipartFile('file', file.getBytes()) 
 
      MockMultipartHttpServletRequestBuilder multipart = (MockMultipartHttpServletRequestBuilder) multipart('/v1/document').with(request -> { 
        request.setMethod(HttpMethod.PUT); 
        return request; 
      }); 
    when: 
      ResultActions result = mockMvc.perform(multipart 
        .file(multipartFile)) 
    then: 
      result.andExpect(status().isCreated()) 
  } 
} 

诀窍是使用 with(RequestPostProcessor postProcessor)修改请求并将方法 PUT 设置为它。