使用MockMultipartHttpServletRequest进行unit testing(在ItemInputStream.makeAvailable中抛出NullPointerException)
我编写了一个带有HttpServletRequest的转换器类,并将其转换为另一种类型,该类型包含一个指向来自servlet请求的InputStream的指针。 (这个想法是从请求处理中抽象出传输传输协议,所以我也可以从FTP编写类似的转换器。)
现在我正在尝试为此编写一个unit testing,我遇到了问题。 我已经设法找出正确的样板来创建有效的Multipart HTTP请求(使用Spring类MockMultipartHttpServletRequest和MockMultipartFile),但现在我在UploadRequest
类的initialize()
方法中得到NullPointerException。 我猜测问题是,MockMultipartHttpServletRequest内部的流不是正确初始化,但我无法弄清楚我应该做些什么不同。
任何建议都会感激不尽!
这是堆栈跟踪:
java.lang.NullPointerException at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:976) at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:886) at java.io.InputStream.read(InputStream.java:82) at org.apache.commons.fileupload.util.Streams.copy(Streams.java:96) at org.apache.commons.fileupload.util.Streams.copy(Streams.java:66) at org.apache.commons.fileupload.MultipartStream.readBodyData(MultipartStream.java:592) at org.apache.commons.fileupload.MultipartStream.discardBodyData(MultipartStream.java:618) at org.apache.commons.fileupload.MultipartStream.skipPreamble(MultipartStream.java:637) at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:984) at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.(FileUploadBase.java:965) at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331) at org.apache.commons.fileupload.servlet.ServletFileUpload.getItemIterator(ServletFileUpload.java:148) at com.ooyala.UploadRequest.initialize(UploadRequest.java:51) at com.ooyala.UploadRequestTest.testCreateFromServletRequest(UploadRequestTest.java:57)
这是我的变压器类的缩写版本:
public class UploadRequest { private Map params; private InputStream strIn; private Logger Log = Logger.getLogger(UploadRequest.class.getName()); public UploadRequest() { params = new HashMap(); } public void initialize(HttpServletRequest sRequest, ServletFileUpload upload) throws IOException, FileUploadException { Enumeration paramNames = sRequest.getParameterNames(); while (paramNames.hasMoreElements()) { String pName = paramNames.nextElement(); params.put(pName, sRequest.getParameter(pName)); } params.put("request_uri", sRequest.getRequestURI()); FileItemIterator iter = upload.getItemIterator(sRequest); while (iter.hasNext()) { FileItemStream item = iter.next(); try { if (!item.isFormField()) { // Skip form fields params.put("original_file_name", item.getName()); strIn = item.openStream(); } } catch (IOException ex) { Log.severe("File uploading exception: " + ex.getMessage()); throw ex; } } }
这是unit testing:
import org.springframework.mock.web.MockMultipartHttpServletRequest; import org.springframework.mock.web.MockMultipartFile; import org.apache.commons.fileupload.servlet.ServletFileUpload; // etc.... other imports @RunWith(JMock.class) public class UploadRequestTest { private UploadRequest upRequest; @Before public void setUp() { context.setImposteriser(ClassImposteriser.INSTANCE); upRequest = new UploadRequest(); } @Test public void testCreateFromServletRequest() throws IOException, FileUploadException { String text_contents = "hello world"; MockMultipartHttpServletRequest sRequest = new MockMultipartHttpServletRequest(); sRequest.setMethod("POST"); String boundary = generateBoundary(); String contentType = "multipart/form-data; boundary="+boundary; sRequest.setContentType(contentType); sRequest.setRequestURI("/foo"); sRequest.addParameter("test_param","test_value"); sRequest.addFile( new MockMultipartFile("file1","test_upload.txt","text/plain", text_contents.getBytes())); ServletFileUpload upload = new ServletFileUpload(); assertTrue(upload.isMultipartContent(sRequest)); upRequest.initialize(sRequest, upload); } }
我有同样的问题,我用谷歌搜索,但没有答案。 我插入了库中的源代码,你需要发送内容,无论如何。 库可能需要检查skip方法中是否为null
MockMultipartHttpServletRequest request request.setContent("whatever".getBytes());
在这里张贴给其他人
- 添加边界条件
-
生成内容如下
MockMultipartHttpServletRequest request = this.generateMockMultiPartHttpServletRequest(true); MockMultipartFile mockMultipartFile = null; try { request.setContentType("multipart/form-data; boundary=-----1234"); request.setCharacterEncoding("text/plain"); String endline = "\r\n"; String bondary = "-----1234"; String textFile = this.encodeTextFile("-----1234", "\r\n", "file","test.csv", "text/UTF-8", FileUtils.readFileToString((new File(csvFilePath)), "UTF-8")); StringBuilder content = new StringBuilder(textFile.toString()); content.append(endline); content.append(endline); content.append(endline); content.append("--"); content.append(bondary); content.append("--"); content.append(endline); request.setContent(content.toString().getBytes()); request.setMethod("POST"); mockMultipartFile = new MockMultipartFile("file", FileUtils.readFileToByteArray(new File(csvFilePath))); } catch (Exception e1) { e1.printStackTrace(); } request.addFile(mockMultipartFile);
编码文本的function
private String encodeTextFile(String bondary, String endline, String name, String filename, String contentType, String content) { final StringBuilder sb = new StringBuilder(64); sb.append(endline); sb.append("--"); sb.append(bondary); sb.append(endline); sb.append("Content-Disposition: form-data; name=\""); sb.append(name); sb.append("\"; filename=\""); sb.append(filename); sb.append("\""); sb.append(endline); sb.append("Content-Type: "); sb.append(contentType); sb.append(endline); sb.append(endline); sb.append(content); return sb.toString(); }
我经历了同样的问题,经过搜索很多我得到了这篇post,其中我回答了解决我问题的代码。
Shriprasad的解决方案适用于文本文件。 但我在二进制文件方面遇到了一些问题。