How to Mock a javax.servlet.ServletInputStream

inputstream, java, mockito, servlets, unit-testing

Solution

Don't mock the InputStream. Instead, transform the String to an array of bytes using the getBytes() method. Then create a ByteArrayInputStream with the array as input, so that it returns the String when consumed, each byte at a time. Next, create a ServletInputStream that wraps a regular InputStream like the one from Spring:

public class DelegatingServletInputStream extends ServletInputStream {

    private final InputStream sourceStream;


    /**
     * Create a DelegatingServletInputStream for the given source stream.
     * @param sourceStream the source stream (never <code>null</code>)
     */
    public DelegatingServletInputStream(InputStream sourceStream) {
        Assert.notNull(sourceStream, "Source InputStream must not be null");
        this.sourceStream = sourceStream;
    }

    /**
     * Return the underlying source stream (never <code>null</code>).
     */
    public final InputStream getSourceStream() {
        return this.sourceStream;
    }


    public int read() throws IOException {
        return this.sourceStream.read();
    }

    public void close() throws IOException {
        super.close();
        this.sourceStream.close();
    }

}

and finally, the HttpServletRequest mock would return this DelegatingServletInputStream object.

Problem

I am creating some unit testing and trying to Mock out some calls. Here is what I have in my working code: ``` String soapRequest = (SimUtil.readInputStream(request.getInputStream())).toString(); if (soapRequest.equals("My String")) { ... } ``` and SimUtil.readInputSteam looks like this: ``` StringBuffer sb = new StringBuffer(); BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(inputStream)); final int buffSize = 1024; char[] buf = new char[buffSize]; int numRead = 0; while ((numRead = reader.read(buf)) != -1) { String readData = String.valueOf(buf, 0, numRead); sb.append(readData); buf = new char[buffSize]; } } catch (IOException e) { LOG.error(e.getMessage(), e); } finally { try { if (reader != null) { reader.close(); } } catch (IOException e) { LOG.error(e.getMessage(), e); } } ``` What I am trying to do is the request.getInputStream(), the stream returns certain String. ``` HttpServletRequest request = mock(HttpServletRequest.class); ServletInputStream inputStream = mock(ServletInputStream.class); when(request.getInputStream()).thenReturn(inputStream); ``` So This is the code I want to condition ``` when(inputStream.read()).thenReturn("My String".toInt()); ``` Any Help would be greatly appreciated.

Original source

Related problems