java - Spring MVC Junit测试MultipartFile总是空的

标签 java spring-mvc junit mockmvc

我正在使用带有 Junit 4.12 和 java 1.7 的 spring-mvc 版本 4.1.6-RELEASE,我有一个用于文件上传的 Controller ,当我在带有浏览器的服务器上对其进行测试时,该 Controller 可以工作。但是当我尝试用 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" />

这是 Controller
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();
        }
    }
}

在 UploadPianoAttivitaController 的上传方法中,当我运行 Junit 时,参数文件 [] 包含 1 个空的 MultiPartFile,而当我在服务器上运行它并从页面上传文件时,一切正常。

最佳答案

您的姓名 RequestParam文件必须与 MockMultipartFile 匹配姓名。

在你的情况下是“files [] ”,在模拟中是“testJunit ”,你可以看你的 HttpServletRequest Controller 中的参数。

关于java - Spring MVC Junit测试MultipartFile总是空的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30892904/

相关文章:

android - 在 AndroidManifest 元数据中指定自定义 RunListener 不起作用

java - 断言具有嵌套 Map 字段的两个对象不相等

java - 使用 lambda 查找特定扩展名的文件

java - 如何将速度模板加载到 EJB 中以用作邮件模板

java - 如何使用具有不同验证注释的相同表单 DTO?如何避免双重代码?

java - file.html 在本地主机上正确显示,但在服务器上不正确显示

java DateTimeFormatterBuilder 在测试时失败

java - Java Web 应用程序中的异步电子邮件处理

java - 具有当前 elasticsearch 版本的 Spring Boot 应用程序

java - Spring MVC 基于 Java 的配置看不到类路径属性文件