使用SpringMVC测试单元测试多部分POST请求
我有以下用于保存汽车的请求处理程序。我已经验证了当我使用例如cURL时,这是有效的。现在我想用SpringMVC测试对该方法进行单元测试。我曾尝试使用文件上传器,但我没有设法让它工作。我也没有设法添加JSON部分 我如何使用SpringMVC测试对这个方法进行单元测试?我找不到这方面的例子使用SpringMVC测试单元测试多部分POST请求,spring,unit-testing,spring-mvc,Spring,Unit Testing,Spring Mvc,我有以下用于保存汽车的请求处理程序。我已经验证了当我使用例如cURL时,这是有效的。现在我想用SpringMVC测试对该方法进行单元测试。我曾尝试使用文件上传器,但我没有设法让它工作。我也没有设法添加JSON部分 我如何使用SpringMVC测试对这个方法进行单元测试?我找不到这方面的例子 @RequestMapping(value = "autos", method = RequestMethod.POST) public ResponseEntity saveAuto( @Reque
@RequestMapping(value = "autos", method = RequestMethod.POST)
public ResponseEntity saveAuto(
@RequestPart(value = "data") autoResource,
@RequestParam(value = "files[]", required = false) List<MultipartFile> files) {
// ...
}
@RequestMapping(value=“autos”,method=RequestMethod.POST)
公共响应自动保存(
@RequestPart(value=“data”)自动资源,
@RequestParam(value=“files[]”,required=false)列表文件){
// ...
}
我想为我的auto+一个或多个文件上传一个JSON表示
我会在正确答案的基础上再加上100看看这个取自spring MVC showcase的示例,这是指向以下内容的链接:
由于
MockMvcRequestBuilders#fileUpload
已被弃用,因此您需要使用返回。然后连串打电话
这里有一个有效的例子。给定一个@控制器
@Controller
public class NewController {
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String saveAuto(
@RequestPart(value = "json") JsonPojo pojo,
@RequestParam(value = "some-random") String random,
@RequestParam(value = "data", required = false) List<MultipartFile> files) {
System.out.println(random);
System.out.println(pojo.getJson());
for (MultipartFile file : files) {
System.out.println(file.getOriginalFilename());
}
return "success";
}
static class JsonPojo {
private String json;
public String getJson() {
return json;
}
public void setJson(String json) {
this.json = json;
}
}
}
以及@配置
类
@Configuration
@ComponentScan({ "test.controllers" })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurationSupport {
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
return multipartResolver;
}
}
测试应该通过,并为您提供
4 // from param
someValue // from json file
filename.txt // from first file
other-file-name.data // from second file
需要注意的是,您发送的JSON与任何其他多部分文件一样,只是内容类型不同。方法
MockMvcRequestBuilders.fileUpload
不推荐使用MockMvcRequestBuilders.multipart
这是一个例子:
import static org.hamcrest.CoreMatchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.MultipartFile;
/**
* Unit test New Controller.
*
*/
@RunWith(SpringRunner.class)
@WebMvcTest(NewController.class)
public class NewControllerTest {
private MockMvc mockMvc;
@Autowired
WebApplicationContext wContext;
@MockBean
private NewController newController;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(wContext)
.alwaysDo(MockMvcResultHandlers.print())
.build();
}
@Test
public void test() throws Exception {
// Mock Request
MockMultipartFile jsonFile = new MockMultipartFile("test.json", "", "application/json", "{\"key1\": \"value1\"}".getBytes());
// Mock Response
NewControllerResponseDto response = new NewControllerDto();
Mockito.when(newController.postV1(Mockito.any(Integer.class), Mockito.any(MultipartFile.class))).thenReturn(response);
mockMvc.perform(MockMvcRequestBuilders.multipart("/fileUpload")
.file("file", jsonFile.getBytes())
.characterEncoding("UTF-8"))
.andExpect(status().isOk());
}
}
如果您使用的是Spring4/SpringBoot 1.x,那么值得一提的是,您还可以添加“文本”(json)部分。这可以通过MockMvcRequestBuilders.fileUpload().file(MockMultipartFile文件)完成(该文件是必需的,因为方法
。multipart()
在此版本中不可用):
以下是对我有效的方法,我将在测试中向EmailController附加一个文件。还可以看看邮递员截图,了解我是如何发布数据的
@WebAppConfiguration
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = EmailControllerBootApplication.class
)
public class SendEmailTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Test
public void testSend() throws Exception{
String jsonStr = "{\"to\": [\"email.address@domain.com\"],\"subject\": "
+ "\"CDM - Spring Boot email service with attachment\","
+ "\"body\": \"Email body will contain test results, with screenshot\"}";
Resource fileResource = new ClassPathResource(
"screen-shots/HomePage-attachment.png");
assertNotNull(fileResource);
MockMultipartFile firstFile = new MockMultipartFile(
"attachments",fileResource.getFilename(),
MediaType.MULTIPART_FORM_DATA_VALUE,
fileResource.getInputStream());
assertNotNull(firstFile);
MockMvc mockMvc = MockMvcBuilders.
webAppContextSetup(webApplicationContext).build();
mockMvc.perform(MockMvcRequestBuilders
.multipart("/api/v1/email/send")
.file(firstFile)
.param("data", jsonStr))
.andExpect(status().is(200));
}
}
fileUpload
被弃用,取而代之的是多部分(字符串、对象…)
。
import static org.hamcrest.CoreMatchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.MultipartFile;
/**
* Unit test New Controller.
*
*/
@RunWith(SpringRunner.class)
@WebMvcTest(NewController.class)
public class NewControllerTest {
private MockMvc mockMvc;
@Autowired
WebApplicationContext wContext;
@MockBean
private NewController newController;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(wContext)
.alwaysDo(MockMvcResultHandlers.print())
.build();
}
@Test
public void test() throws Exception {
// Mock Request
MockMultipartFile jsonFile = new MockMultipartFile("test.json", "", "application/json", "{\"key1\": \"value1\"}".getBytes());
// Mock Response
NewControllerResponseDto response = new NewControllerDto();
Mockito.when(newController.postV1(Mockito.any(Integer.class), Mockito.any(MultipartFile.class))).thenReturn(response);
mockMvc.perform(MockMvcRequestBuilders.multipart("/fileUpload")
.file("file", jsonFile.getBytes())
.characterEncoding("UTF-8"))
.andExpect(status().isOk());
}
}
@Test
public void test() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.fileUpload("/files")
// file-part
.file(makeMultipartFile( "file-part" "some/path/to/file.bin", "application/octet-stream"))
// text part
.file(makeMultipartTextPart("json-part", "{ \"foo\" : \"bar\" }", "application/json"))
.andExpect(status().isOk())));
}
private MockMultipartFile(String requestPartName, String filename,
String contentType, String pathOnClassPath) {
return new MockMultipartFile(requestPartName, filename,
contentType, readResourceFile(pathOnClasspath);
}
// make text-part using MockMultipartFile
private MockMultipartFile makeMultipartTextPart(String requestPartName,
String value, String contentType) throws Exception {
return new MockMultipartFile(requestPartName, "", contentType,
value.getBytes(Charset.forName("UTF-8")));
}
private byte[] readResourceFile(String pathOnClassPath) throws Exception {
return Files.readAllBytes(Paths.get(Thread.currentThread().getContextClassLoader()
.getResource(pathOnClassPath).toUri()));
}
}
@WebAppConfiguration
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = EmailControllerBootApplication.class
)
public class SendEmailTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Test
public void testSend() throws Exception{
String jsonStr = "{\"to\": [\"email.address@domain.com\"],\"subject\": "
+ "\"CDM - Spring Boot email service with attachment\","
+ "\"body\": \"Email body will contain test results, with screenshot\"}";
Resource fileResource = new ClassPathResource(
"screen-shots/HomePage-attachment.png");
assertNotNull(fileResource);
MockMultipartFile firstFile = new MockMultipartFile(
"attachments",fileResource.getFilename(),
MediaType.MULTIPART_FORM_DATA_VALUE,
fileResource.getInputStream());
assertNotNull(firstFile);
MockMvc mockMvc = MockMvcBuilders.
webAppContextSetup(webApplicationContext).build();
mockMvc.perform(MockMvcRequestBuilders
.multipart("/api/v1/email/send")
.file(firstFile)
.param("data", jsonStr))
.andExpect(status().is(200));
}
}