【问题标题】:Spring MVC 4.2 : How to Unit Test Controller with @RequestPart ParamsSpring MVC 4.2:如何使用 @RequestPart 参数对控制器进行单元测试
【发布时间】:2019-07-14 01:27:33
【问题描述】:

我有一个 requestMapping 的形式:

@RequestMapping(
    value = "/submitCase",
    consumes =  MediaType.MULTIPART_FORM_DATA_VALUE,
    produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
    method = RequestMethod.POST
)
public Object submitCase(
    @RequestPart(name = "attachment[0]", required = false) MultipartFile attachment1,
    @RequestPart(name = "attachment[1]", required = false) MultipartFile attachment2,
    @RequestPart(name = "attachment[2]", required = false) MultipartFile attachment3,
    @RequestPart(name = "attachment[3]", required = false) MultipartFile attachment4,
    @RequestPart(name = "attachment[4]", required = false) MultipartFile attachment5,
    @RequestPart(name = "caseDetails") CaseDetails caseDetails) {}

现在我想用 MockMvcBuilders 写一个测试。但是我不能这样做。

这里的挑战是请求处理程序使用 multipart/form-data,它由 4 个 Multipart 文件和 1 个 Json 数据组成。

关于如何解决这个问题的任何想法?请记住,我只能使用 Spring 4.3。

如果您需要更多信息,请告诉我。

【问题讨论】:

  • 我的回答是否有助于解决您的问题?

标签: unit-testing spring-mvc testing mockmvc


【解决方案1】:

看看这里的好例子:https://stackoverflow.com/a/21805186/3976662

请注意,示例中使用的MockMvcRequestBuilders.html#multipart 在 Spring 4.3.0 中尚不可用。请改用MockMvcRequestBuilders.html#fileUpload(在 Spring 5 中已弃用)。

CaseDetails.java:

public class CaseDetails {
    private String exampleAttr;

    public String getExampleAttr() {
        return exampleAttr;
    }

    public void setExampleAttr(String exampleAttr) {
        this.exampleAttr = exampleAttr;
    }
}

上传控制器.java:

@Controller
public class UploadController {

    @RequestMapping(
            value = "/submitCase",
            consumes =  MediaType.MULTIPART_FORM_DATA_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
            method = RequestMethod.POST
    )
    @ResponseBody
    public Object submitCase(
            @RequestPart(name = "attachment[0]", required = false) MultipartFile attachment1,
            @RequestPart(name = "attachment[1]", required = false) MultipartFile attachment2,
            @RequestPart(name = "attachment[2]", required = false) MultipartFile attachment3,
            @RequestPart(name = "attachment[3]", required = false) MultipartFile attachment4,
            @RequestPart(name = "attachment[4]", required = false) MultipartFile attachment5,
            @RequestPart(name = "caseDetails") CaseDetails caseDetails) {

        Map<String,String> result = new HashMap<>();
        result.put("success", "true");

        return result;
    }
}

上传控制器测试.java:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = UploadControllerTest.TestConfig.class)
public class UploadControllerTest {

    @Autowired
    private UploadController uploadController;

    @Test
    public void testSubmitCase() throws Exception {
        MockMultipartFile file1 = new MockMultipartFile("attachment[0]", "filename-1.txt", "text/plain", "1".getBytes());
        MockMultipartFile file2 = new MockMultipartFile("attachment[1]", "filename-2.txt", "text/plain", "2".getBytes());
        MockMultipartFile file3 = new MockMultipartFile("attachment[2]", "filename-3.txt", "text/plain", "3".getBytes());
        MockMultipartFile file4 = new MockMultipartFile("attachment[3]", "filename-4.txt", "text/plain", "4".getBytes());
        MockMultipartFile file5 = new MockMultipartFile("attachment[4]", "filename-5.txt", "text/plain", "5".getBytes());

        MockMultipartFile caseDetailsJson = new MockMultipartFile("caseDetails", "", "application/json","{\"exampleAttr\": \"someValue\"}".getBytes());

        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(uploadController).build();
        mockMvc.perform(MockMvcRequestBuilders.fileUpload("/submitCase")
                .file(file1)
                .file(file2)
                .file(file3)
                .file(file4)
                .file(file5)
                .file(caseDetailsJson))
                    .andDo(MockMvcResultHandlers.print())
                    .andExpect(MockMvcResultMatchers.content().string("{\"success\":\"true\"}"))
                    .andReturn();
    }

    @Configuration
    static class TestConfig {

        @Bean
        public UploadController uploadController() {
            return new UploadController();
        }
    }
}

请注意,UploadControllerTest 中的 JSON 数据必须包含在 MockMultipartFile 中 - 相当于上传的文件。确保 jackson-corejackson-databind 在类路径中可用。

【讨论】:

  • 嘿,我尝试使用它,但我还需要为 CaseDetails 参数发送 json 数据。我不能使用 fileUpload 来做到这一点。有什么想法吗?
  • 我更新了我的答案。从 Spring MockMvc 4.3.0 的角度来看,multipart/form-data 请求上下文中的 JSON 的处理方式与文件相同:将数据包装在 MockMultipartFile 中。为了指出这一点,我扩展了这个例子。这对你有用吗?
猜你喜欢
  • 2010-11-26
  • 2014-02-08
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 2012-05-25
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
相关资源
最近更新 更多