Spring MVC 4.2:如何使用@RequestPart参数对控制器进行单元测试

3

我有一个这样的请求映射:

@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个多部分文件和1个Json数据。
有什么解决方法吗?请注意,我只能使用Spring 4.3。
如果您需要更多信息,请告诉我。

我的回答有帮助解决你的问题吗? - seb.wired
1个回答

5
请看这个优秀的示例:https://dev59.com/O2Eh5IYBdhLWcg3w_Xv5#21805186 注意,在该示例中使用的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;
    }
}

UploadController.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;
    }
}

UploadControllerTest.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在类路径上可用。

嘿,我尝试使用那个,但我还需要发送JSON数据作为CaseDetails参数。我无法使用fileUpload完成这个任务。有什么想法吗? - user3762085
我更新了我的回答。从Spring MockMvc 4.3.0的角度来看,针对multipart/form-data请求的JSON与文件的处理方式相同:将数据包装在MockMultipartFile中。我扩展了示例以便指出这一点。这对你有用吗? - seb.wired

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接