2012-02-28 5 views
7

He escrito una clase de transformador que toma una HttpServletRequest y la transforma en otro tipo que contiene un puntero al InputStream desde la solicitud del servlet. (La idea es abstraer el protocolo de transporte entrante del manejo de solicitudes, por lo que también podría escribir un transformador similar de FTP, por ejemplo).Pruebas unitarias utilizando MockMultipartHttpServletRequest (throws NullPointerException en ItemInputStream.makeAvailable)

Ahora intento escribir una prueba unitaria para esto, y yo ' Estoy teniendo problemas. Me las he arreglado para encontrar la plantilla correcta para crear una solicitud HTTP Multipart válida (usando las clases Spring MockMultipartHttpServletRequest y MockMultipartFile), pero ahora obtengo una NullPointerException en el método initialize() de mi clase UploadRequest. Supongo que el problema es que, de alguna manera, la secuencia dentro de MockMultipartHttpServletRequest no se está inicializando correctamente, pero no puedo entender qué debo hacer de manera diferente.

¡Cualquier sugerencia será gratamente aceptada!

Este es el seguimiento de la pila:

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) 

Aquí es una versión abreviada de mi clase del transformador:

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

y aquí está la prueba de unidad:

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

Respuesta

1

Tengo el mismo problema y busqué en Google, pero sin respuesta. Conecté el código fuente de la biblioteca, necesitas enviar contenido, lo que sea. La biblioteca puede ser que necesite para comprobar si es nula en el método de salto

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

Publicado aquí para otros

1
  1. Añadir condición de contorno
  2. Generar contenidos de la siguiente manera

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

Función para codificar el texto

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

Pasé por el mismo problema, después de buscar mucho conseguí esta publicación en la que respondí con el código que resolvió mi problema.

La solución Shriprasad funciona bien para archivos de texto. Pero tuve algunos problemas con los archivos binarios.

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