zoukankan      html  css  js  c++  java
  • spring boot单元测试之四:单元测试中测试文件上传(spring boot 2.4.3)

    一,演示项目的相关信息

    1,地址:

    https://github.com/liuhongdi/fileuptest

    2,功能说明:演示了在单元测试中如何测试文件上传

    3,项目结构:如图:

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: https://github.com/liuhongdi/

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,配置文件说明

    1,application.yml

    #thymeleaf
    spring:
      thymeleaf:
        cache: false
        encoding: UTF-8
        mode: HTML
        prefix: classpath:/templates/
        suffix: .html
    #upload
      servlet:
        multipart:
          maxFileSize: 10MB
          maxRequestSize: 30MB
    #tomcat,
    server:
      tomcat:
        connection-timeout: 20000
        max-http-form-post-size: 30MB
    #error
      error:
        include-stacktrace: always
    #errorlog
    logging:
      level:
        org.springframework.web: trace

    三,java代码说明

    1,controller/FileController.java

    @Controller
    @RequestMapping("/file")
    public class FileController {
    
        //文件的保存路径
        private final static String FILE_BASE_PATH = "/data/file/html";
    
        //单文件/多文件上传页面
        @GetMapping("/upload")
        public String upload(ModelMap modelMap) {
            return "image/upload";
        }
    
        //处理单文件/多文件上传
        @PostMapping("/uploaded")
        @ResponseBody
        public RestResult uploaded(HttpServletRequest request) {
    
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            System.out.println("是否有上传文件:"+isMultipart);
            if (isMultipart == false) {
                return RestResult.error(1,"表单中不含文件");
            }
            List<MultipartFile> list = ((MultipartHttpServletRequest)request).getFiles("files");
            if (list.isEmpty()) {
                return RestResult.error(1,"文件不存在");
            }
            for (MultipartFile multipartFile : list) {
                if (list.isEmpty()) {
                    continue;
                }
    
                // 文件名
                String fileName = multipartFile.getOriginalFilename();
                System.out.println("文件名: " + fileName);
                // file size:
                Long length = multipartFile.getSize();
                System.out.println("files size :"+length);
    
                // 文件后缀
                int lastDot = fileName.lastIndexOf(".");
                lastDot++;
                String fileType = fileName.substring(lastDot);
                    // 重新生成唯一文件名,用于存储数据库
                    String fileSn = UUID.randomUUID().toString();
                    Map<String, String> map2 = new HashMap<String, String>();
                    String destFilePath = FILE_BASE_PATH+"/"+fileSn+"."+fileType;
                    File dest = new File(destFilePath);
                    try {
                        multipartFile.transferTo(dest);
                    } catch (IOException e) {
                        System.out.println("save ioexception");
                        e.printStackTrace();
                        return RestResult.error(1,"上传失败");
                    }
            }
            return RestResult.success(0,"上传成功");
        }
    }

    2,result/RestResult.java

    //api通用返回数据
    public class RestResult<T> {
    
        //uuid,用作唯一标识符,供序列化和反序列化时检测是否一致
        private static final long serialVersionUID = 7498483649536881777L;
        //标识代码,0表示成功,非0表示出错
        private Integer code;
    
        //提示信息,通常供报错时使用
        private String msg;
    
        //正常返回时返回的数据
        private T data;
    
        //constructor
        public RestResult() {
        }
    
        //constructor
        public RestResult(Integer status, String msg, T data) {
            this.code = status;
            this.msg = msg;
            this.data = data;
        }
    
        //返回成功数据
        public RestResult success(T data) {
            return new RestResult(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMsg(), data);
        }
    
        public static RestResult success(Integer code,String msg) {
            return new RestResult(code, msg, null);
        }
    
        //返回出错数据
        public static RestResult error(ResponseCode code) {
            return new RestResult(code.getCode(), code.getMsg(), null);
        }
    
        public static RestResult error(Integer code,String msg) {
            return new RestResult(code, msg, null);
        }
    
        public Integer getCode() {
            return code;
        }
        public void setCode(Integer code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public T getData() {
            return data;
        }
        public void setData(T data) {
            this.data = data;
        }
    }

    3,templates/image/upload.html

    <html lang="en">
    <head>
        <script type="text/javascript" language="JavaScript" src="/js/jquery-1.6.2.min.js"></script>
    </head>
    <body>
    <div style="100%;height:20px;background:#ffffff;font-size: 16px;" ></div>
    <div id="content" style="800px;">
        <div style="800px;float:left;">
           <!--====================main begin=====================-->
            <div style="260px;height:200px;float:left;background: #eeeeee;padding-left: 10px;padding-top: 10px;">
                单文件上传<br/>
                说明:不能多选<br/>
                <input id="fileone" type="file" name="fileone" /><br/><br/>
                <input type="button" name="go" value="单文件上传" onclick="go_single_add()" />
            </div>
            <!--====================main   end=====================-->
        </div>
    </div>
    
    <script>
        //单文件上传
        function go_single_add(){
            //把表单中选中的文件添加到postdata
            var postdata=new FormData();
            for (var i=0;i<$("#fileone")[0].files.length;i++){
                postdata.append("files",$("#fileone")[0].files[i])
            }
            $.ajax({
                type:"POST",
                url:"/file/uploaded",
                data:postdata,
                //返回数据的格式
                datatype: "json",//"xml", "html", "script", "json", "jsonp", "text".
                processData: false,
                contentType: false,
                //成功返回之后调用的函数
                success:function(data){
                    if (data.code == 0) {
                        alert('上传成功:'+data.msg);
                        //window.location.href="/image/imagelist";
                    } else {
                        alert("上传失败:"+data.msg);
                    }
                },
                //调用执行后调用的函数
                complete: function(XMLHttpRequest, textStatus){
                },
                //调用出错执行的函数
                error: function(XMLHttpRequest, textStatus, errorThrown){
                    alert(XMLHttpRequest.readyState + XMLHttpRequest.status + XMLHttpRequest.responseText);
                }
            });
        }
    
    </script>
    </body>
    </html>

    4,controller/FileControllerTest.java

    import com.jayway.jsonpath.JsonPath;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.MediaType;
    import org.springframework.mock.web.MockMultipartFile;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.nio.charset.StandardCharsets;
    
    import static org.junit.jupiter.api.Assertions.*;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
    //import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    import static org.hamcrest.MatcherAssert.assertThat;
    import static org.hamcrest.Matchers.equalTo;
    @AutoConfigureMockMvc
    @SpringBootTest
    class FileControllerTest {
    
        @Autowired
        private MockMvc mockMvc;
    
        @Test
        @DisplayName("上传文件成功")
        void uploaded() throws Exception {
            //文件之外的参数
            String key1 = "这是第一个文件的说明";
            String key2 = "这是第二个文件的说明";
    
            File file2 = new File("/data/image/2.jpg");
            MockMultipartFile mFile2 = new MockMultipartFile("files", "2.jpg",
                    MediaType.TEXT_PLAIN_VALUE, new FileInputStream(file2));
    
            File file3 = new File("/data/image/3.jpg");
            MockMultipartFile mFile3 = new MockMultipartFile("files", "3.jpg",
                    MediaType.TEXT_PLAIN_VALUE, new FileInputStream(file3));
    
            MvcResult mvcResult = mockMvc.perform(multipart("/file/uploaded")
                    .file(mFile2)
                    .file(mFile3)
                    .param("key1", key1)
                    .param("key2", key2))
                    .andExpect(status().isOk())
                    .andReturn();
            String content = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
            System.out.println(content);
            int code = JsonPath.parse(content).read("$.code");
            assertThat(code, equalTo(0));
        }
    
        @Test
        @DisplayName("上传文件失败")
        void uploadedFail() throws Exception {
            //文件之外的参数
            String key1 = "这是第一个文件的说明";
            String key2 = "这是第二个文件的说明";
    
            MvcResult mvcResult = mockMvc.perform(post("/file/uploaded")
                    .param("key1", key1)
                    .param("key2", key2))
                    .andExpect(status().isOk())
                    .andReturn();
            String content = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
            System.out.println(content);
            int code = JsonPath.parse(content).read("$.code");
            assertThat(code, equalTo(1));
        }
    }

    四,测试效果

    1,通过web页面访问

    http://127.0.0.1:8080/file/upload

    上传成功:

    上传失败:

    2,运行测试:

    查看控制台:

    上传成功:

    是否有上传文件:true
    文件名: 2.jpg
    files size :52066
    文件名: 3.jpg
    files size :9576
    {"code":0,"msg":"上传成功","data":null}

    上传失败:

    是否有上传文件:false
    {"code":1,"msg":"表单中不含文件","data":null}

    五,查看spring boot的版本:

      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::                (v2.4.3)
  • 相关阅读:
    vs2013 中如何如何让html页面的设计视图显示
    UITableView
    iOS Quartz2D绘制线、矩形、弧、圆、文字、图片
    iOS Quartz2D模拟下载进度条
    多控制器管理 UITabBarController
    UIApplicationDelegate类
    extern static关键字
    深复制与浅复制
    ios数据存储方式
    UITableView定义分割线
  • 原文地址:https://www.cnblogs.com/architectforest/p/14536911.html
Copyright © 2011-2022 走看看