Domanda

Sto lavorando in un quadro che utilizza commons-fileupload.

Ora ho bisogno di scrivere classi di unit test. Il mio dubbio è come scrivere test finto se ServletFileUpload non è un interfaccia? Ci sono un altro modo per testare le mie lezioni?

Ieri ho scritto unit test utilizzando Mockito per Servlet parti, ed è facile. Ma non riesco a pensare a come scrivere i test per commons-fileupload.

È stato utile?

Soluzione

Si potrebbe tornare alle origini e roll mano il vostro oggetto fittizio da una confezione o di estendere e sovrascrivendo. A volte è più facile di non dipendere da un quadro di scherno per ogni cosa.

Mocking beffardo e test Risultati

Altri suggerimenti

You could use Commons HTTPClient to build the multipart stream:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletFileUploadMock {

    public static class FileUpload {

        private final String filename;
        private final String mimeType;
        private final byte[] contents;

        public FileUpload(String filename, String mimeType, byte[] contents) {
            this.filename = filename;
            this.mimeType = mimeType;
            this.contents = contents;
        }

    }

    public static HttpServletResponse mockServletFileUpload(HttpServlet servlet, List<FileUpload> files,
            Map<String, String> queryParams) throws IOException, ServletException {

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        for (FileUpload f : files) {
            builder = builder.addBinaryBody(f.filename, f.contents, ContentType.create(f.mimeType), f.filename);
        }
        HttpEntity entity = builder.build();

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        entity.writeTo(os);
        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());

        HttpServletRequest mockRequest = mock(HttpServletRequest.class);
        when(mockRequest.getMethod()).thenReturn("POST");
        when(mockRequest.getContentType()).thenReturn(entity.getContentType().getValue());
        when(mockRequest.getContentLength()).thenReturn((int)entity.getContentLength());
        when(mockRequest.getInputStream()).thenReturn(new MockServletInputStream(is));

        // Mock query params
        for (Entry<String, String> p : queryParams.entrySet()) {
            when(mockRequest.getParameter(p.getKey())).thenReturn(p.getValue());
        }

        HttpServletResponse mockResponse = mock(HttpServletResponse.class);

        servlet.service(mockRequest, mockResponse);

        return mockResponse;
    }

    public static class MockServletInputStream extends ServletInputStream {

        private final InputStream delegate;

        public MockServletInputStream(InputStream delegate) {
            this.delegate = delegate;
        }

        @Override
        public int read() throws IOException {
            return delegate.read();
        }

    }
}

I would consider wrapping your FileUpload calls in another layer. While it might sound like overkill, it would allow you to switch upload libraries very quickly with the added ability to better unit test your calls...It seems like you are tightly coupling your app to commons-fileupload...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top