2012-02-28 20 views
7

Napisałem klasę transformatora, która pobiera HttpServletRequest i przekształca ją w inny typ, który przechowuje wskaźnik do InputStream z żądania serwletu. (Chodzi o to, aby pobrać protokół przychodzącego transportu z obsługi żądania, więc mógłbym napisać podobny transformator z FTP, na przykład.)Testowanie jednostkowe za pomocą MockMultipartHttpServletRequest (generuje wyjątek NullPointerException w ItemInputStream.makeAvailable)

Teraz próbuję napisać test jednostkowy na to, a ja " mam problemy. Udało mi się znaleźć poprawną tabelę podstawową, aby utworzyć poprawne żądanie HTTP wieloczęściowe (używając klas Spring MockMultipartHttpServletRequest i MockMultipartFile), ale teraz dostaję wyjątek NullPointerException w metodzie initialize() mojej klasy UploadRequest. Zgaduję, problem polega na tym, że w jakiś sposób strumień wewnątrz MockMultipartHttpServletRequest nie jest poprawnie zainicjalizowany, ale nie mogę dowiedzieć się, co powinienem zrobić inaczej.

Wszelkie sugestie zostaną przyjęte z wdzięcznością!

To jest ślad stosu:

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) 

Oto skrócona wersja mojego klasy transformatora:

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

A oto test jednostka:

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

Odpowiedz

1

mam takie same problem i ja googled, ale nie ma odpowiedzi. Podłączyłem kod źródłowy z biblioteki, musisz wysłać treść, cokolwiek. Biblioteka może trzeba sprawdzić, czy jest null w metodzie przeskoku

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

Użyto tutaj dla innych

1
  1. Dodaj warunek brzegowy
  2. Generowanie zawartości następująco

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

Funkcja do kodowania tekstu

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

Przeszedłem ten sam problem, po przeszukaniu działki otrzymałem ten post, w którym odpowiedziałem kodem, który rozwiązał mój problem.

Rozwiązanie Shriprasad działa dobrze w przypadku plików tekstowych. Ale miałem pewne problemy z plikami binarnymi.

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

Powiązane problemy