我正在使用带有Junit 4.12和java 1.7的spring-mvc版本4.1.6-RELEASE,我有一个用于文件上传的控制器,当我在使用浏览器的服务器上测试它时,它可以工作。但是当我尝试使用junit测试它时,mockfilemultipart总是为空的,我确信在测试类中不是这样。
这是我的servlet-context.xml
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- beans:import resource="../controller-context.xml"/-->
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<context:component-scan base-package="it.isfol.iweb" />
这是控制器
package it.isfol.iweb.controller.pianoattivita;
import it.isfol.iweb.bean.wrappers.PianoAttivitaWrapper;
import it.isfol.iweb.controller.common.IsfolController;
import it.isfol.iweb.exceptions.IWebFatalException;
import it.isfol.iweb.service.pianoattivita.FilePianoAttivitaService;
import it.isfol.iweb.util.SessionConstant;
import java.util.Arrays;
import java.util.Collection;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class UploadPianoAttivitaController extends IsfolController {
/**
*
*/
private static final long serialVersionUID = 5455170192118107020L;
private static final String UPLOAD_PAGE = "upload/upload";
private final Logger logger = LoggerFactory.getLogger(UploadPianoAttivitaController.class);
@Autowired
private FilePianoAttivitaService filePianoAttivitaService;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String uploadHomePage(HttpSession session) {
logger.info("I'm home");
return goToUploadPage(session);
}
@RequestMapping(value = "/uploadInit", method = RequestMethod.GET)
public String uploadPageRedirect(HttpSession session) {
logger.info("redirect into upload");
return goToUploadPage(session);
}
@RequestMapping(value = "/uploadPiano", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String upload(@RequestParam("files[]") MultipartFile[] files, HttpSession session) throws IWebFatalException {
logger.debug("Writing file to disk...");
try {
Collection<PianoAttivitaWrapper> piani = filePianoAttivitaService.getPianoAttivitaWrapperFromFiles(Arrays.asList(files), session.getId());
session.setAttribute(SessionConstant.PIANO_ATTIVITA_LIST_WRAPPER, piani);
} catch (IWebFatalException e) {
throw e;
} catch (Throwable t) {
logger.error(t.getLocalizedMessage(), t);
throw new IWebFatalException(t);
}
return "pianoAttivita";
}
private String goToUploadPage(HttpSession session) {
logger.debug("redirect on upload page");
sessionHelper.clearSessionPianoReference(session);
return UPLOAD_PAGE;
}
public void setFilePianoAttivitaService(FilePianoAttivitaService filePianoAttivitaService) {
this.filePianoAttivitaService = filePianoAttivitaService;
}
}
然后我的抽象类测试
package it.isfol.iweb;
import java.io.IOException;
import java.util.Properties;
import org.junit.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@WebAppConfiguration(value = "src/main/webapp")
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml", "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml" })
public abstract class IsfolIwebTester extends AbstractJUnit4SpringContextTests {
private final Logger logger = LoggerFactory.getLogger(IsfolIwebTester.class);
private Properties testProperties = new Properties();
@Autowired
private WebApplicationContext webapp;
protected MockMvc mockMvc;
@Before
public void setup() {
logger.debug("reading properties");
try {
testProperties.load(this.getClass().getResourceAsStream("/test-conf.properties"));
this.mockMvc = MockMvcBuilders.webAppContextSetup(webapp).build();
} catch (IOException e) {
logger.error(e.getMessage(), e);
} catch (Throwable e) {
logger.error(e.getLocalizedMessage(), e);
}
}
public String getProperty(String key) {
return testProperties.getProperty(key);
}
}
最后是扩展上面类的测试类
package it.isfol.iweb.pianoattivita;
import it.isfol.iweb.IsfolIwebTester;
import org.apache.commons.io.FilenameUtils;
import org.apache.tika.io.IOUtils;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
public class FilePianoAttivitaTester extends IsfolIwebTester {
private final Logger logger = LoggerFactory.getLogger(FilePianoAttivitaTester.class);
@Test
public void testRunning() {
logger.debug("Test started");
try {
String originalFile = getProperty("test.file.pianoattivita.path");
String originalName = FilenameUtils.getName(originalFile);
byte[] content = IOUtils.toByteArray(getClass().getResourceAsStream(originalFile));
MockMultipartFile file = new MockMultipartFile("testJunit", originalName, null, content);
this.mockMvc.perform(MockMvcRequestBuilders.fileUpload("/uploadPiano").file(file)).andExpect(MockMvcResultMatchers.status().isOk()).andReturn().equals("pianoAttivita");
this.mockMvc.perform(MockMvcRequestBuilders.get("/pianoAttivita")).andExpect(MockMvcResultMatchers.view().name("upload/upload"));
} catch(Throwable t) {
logger.error(t.getLocalizedMessage(), t);
Assert.fail();
}
}
}
在运行Junit的UploadPianoAttivitaController的方法上传时,param文件[]包含1个空的MultiPartFile,而当我在服务器上运行它并从页面上传文件时,一切正常。
答案 0 :(得分:0)
RequestParam
个文件的名称必须与MockMultipartFile
名称匹配。
在你的情况下是“files []
”并且在模拟中是“testJunit
”,你可以在你的控制器中看到你的HttpServletRequest
参数。
答案 1 :(得分:0)
尝试这种方式:
MockMultipartFile mockMultipartFile = new MockMultipartFile("file",
"OriginalName.txt",
"text/plain",
rateExceptionsFile);
mockMvc.perform(multipart(BASE_PATH + "/uploadFile")
.file(mockMultipartFile)
.contentType(MediaType.MULTIPART_FORM_DATA))
.andExpect(status().isOk());