Question

Je travaille dans un cadre qui utilise commons-fileupload.

Maintenant, je dois écrire des classes de tests unitaires. Mon doute est de savoir comment écrire des tests simulés si ServletFileUpload n'est pas une interface? Il y a une autre façon de tester mes cours?

Hier, je l'ai écrit des tests unitaires à l'aide Mockito pour Servlet pièces, et il est facile. Mais je ne peux pas penser à écrire des tests pour commons-fileupload.

Était-ce utile?

La solution

Vous pourriez revenir à l'essentiel et rouler à la main votre objet fantaisie soit par l'emballage ou l'extension et dominante. Parfois, il est plus facile de ne pas dépendre d'un cadre moqueur pour tout.

Mocking Mocking et les résultats d'essai

Autres conseils

Vous pouvez utiliser Commons HttpClient pour construire le flux multipart:

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

    }
}

J'envisagerait d'emballer vos appels fileUpload dans une autre couche. Bien que cela puisse paraître exagéré, il vous permettra de passer des bibliothèques de téléchargement très rapidement grâce à la possibilité de mieux test unitaire vos appels ... Il semble que vous COUPling bien votre application commons-fileupload ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top