如何测试Grails单文件上传控制器及指定Content-Type的二进制请求方法
解决Grails非Multipart类型的文件上传控制器测试问题
你说得没错,GrailsMockHttpServletRequest的addFile方法确实会自动把请求类型设为multipart/form-data,而且它自带的方法大多针对JSON/XML这类结构化请求,要测试纯二进制或者指定非multipart类型的上传,得换个思路——直接操作请求的输入流来模拟原始的请求体。下面针对你的两个问题分别给出解决方案:
1. 测试非multipart/form-data的单文件上传控制器
这种场景下,我们不需要依赖框架封装的文件上传方法,直接把文件的二进制数据写入请求的输入流,同时设置对应的请求头即可:
void "test non-multipart single file upload"() { given: def uploadController = new YourFileUploadController() def request = uploadController.request as GrailsMockHttpServletRequest // 准备测试用的文件 def testFile = new File("src/test/resources/test-file.pdf") def fileBytes = testFile.bytes when: // 设置请求头,根据你的控制器预期的Content-Type来填,比如application/octet-stream request.contentType = "application/octet-stream" request.contentLength = fileBytes.length // 把文件字节流写入请求输入流 request.inputStream = new ByteArrayInputStream(fileBytes) // 调用控制器的上传方法 uploadController.handleNonMultipartUpload() then: // 这里根据你的业务逻辑添加断言,比如响应状态、处理结果等 response.status == HttpStatus.OK.value() uploadController.response.json.success == true }
核心思路是跳过GrailsMockHttpServletRequest的multipart封装,直接模拟原生HTTP请求的二进制体,让控制器接收到和真实场景一致的请求数据。
2. 测试要求Content-Type为image/jpeg的二进制请求体的控制器方法
这个场景和上面类似,只是需要把请求头的Content-Type明确设为image/jpeg,同时确保请求体是纯JPEG图片的二进制数据:
void "test image/jpeg binary request controller method"() { given: def imageController = new ImageProcessingController() def request = imageController.request as GrailsMockHttpServletRequest // 准备测试用的JPG图片 def testImage = new File("src/test/resources/test-image.jpg") def imageBytes = testImage.bytes when: // 指定Content-Type为image/jpeg request.contentType = "image/jpeg" request.contentLength = imageBytes.length request.inputStream = new ByteArrayInputStream(imageBytes) // 调用控制器的图片处理方法 imageController.processRawImage() then: // 断言业务逻辑结果,比如图片是否被正确解析、响应是否符合预期 response.status == 200 imageController.response.json.imageWidth == 800 }
这种方式完全模拟了客户端直接发送二进制JPEG数据的请求,完美匹配控制器对请求头和请求体的要求,避开了GrailsMockHttpServletRequest在非multipart场景下的限制。
内容的提问来源于stack exchange,提问作者kai-dj
相关产品推荐
相关产品推荐

