2012-02-28 55 views
7

我已經編寫了一個轉換器類,它接受一個HttpServletRequest並將其轉換爲另一個類型,該類型包含一個指向來自Servlet請求的InputStream的指針。 (這個想法是從請求處理中抽象傳入的傳輸協議,所以我也可以從FTP寫一個類似的變換器。)使用MockMultipartHttpServletRequest進行單元測試(在ItemInputStream.makeAvailable中拋出NullPointerException)

現在我正在爲此寫一個單元測試,有問題。我已經設法找出正確的樣板來創建一個有效的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.<init>(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<String, String> params; 
    private InputStream strIn; 
    private Logger Log = Logger.getLogger(UploadRequest.class.getName()); 

    public UploadRequest() 
    { 
    params = new HashMap<String, String>(); 
    } 

    public void initialize(HttpServletRequest sRequest, 
         ServletFileUpload upload) 
    throws IOException, FileUploadException 
    { 
    Enumeration<String> 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; 
     } 
    } 
    } 

而這裏的單元測試:

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); 
    } 
} 

回答

1

我有同樣的問題和我Google搜索,但沒有答案。我插入了庫中的源代碼,無論如何你都需要發送內容。該庫可能需要檢查它是否在跳躍的方法無效

MockMultipartHttpServletRequest request 
request.setContent("whatever".getBytes()); 

這裏發佈他人

1
  1. 添加邊界條件
  2. 生成內容如下

    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); 
    

對文字進行編碼的功能

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(); 
    } 
1

我經歷了同樣的問題,搜索了很多後,我得到了這篇文章,我用解決了我的問題的代碼回答。

Shriprasad的解決方案適用於文本文件。但是我有一些二進制文件的問題。

https://stackoverflow.com/a/30541653/2762092

相關問題