Mocking a server-client connection with Mockito
<h1>Introduction</h1>
<p>I'm attempting to test a socket connection by sending a string from one thread to another, where server and client sockets are mocked with Mockito v1.9.5.</p>
<p>Here's the test I'm trying to run:</p>
<pre><code>@Test
public void testConnection() {        
    //associate a mock server socket with the TCP Connection
    TcpSocketConnection connection = new TcpSocketConnection(mockServerSocket);
    try {
        //begin thread which listens for clients, then sends &quot;Hello, world&quot; to a connected
        //client.
        connection.listen();
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(mockTestClientSocket.getInputStream(), DEFAULT_CHARSET)
        );

        long startTime = System.nanoTime();
        for (long interval = 0;
                interval &lt; TIMEOUT_TIME;
                interval = System.nanoTime() - startTime) {
            if (reader.ready()) {
                String receivedMessage = reader.readLine();
                assertEquals(&quot;Hello, world!&quot;, receivedMessage);
                mockTestClientSocket.close();
                connection.closeSocket();
                return;
            }
        }
        mockTestClientSocket.close();
        connection.closeSocket();
        fail(&quot;Failed to receive message.&quot;);
    } catch (IOException e) {
        fail(e.getMessage());
    }
}
</code></pre>
<p>The test runs until <code>TIMEOUT_TIME</code> and then the assertion that fails is the <code>&quot;Failed to receive message.&quot;</code>
I specify the behavior of the mocked objects here:</p>
<pre><code>@Before
public void setup() {
    mockServerSocket = mock(ServerSocket.class);
    try {
        when(mockServerSocket.accept()).thenReturn(mockTestClientSocket);
    } catch (IOException e) {
        fail(e.getMessage());
    }

    mockTestClientSocket = mock(Socket.class);
    try {
        PipedOutputStream oStream = new PipedOutputStream();
        when(mockTestClientSocket.getOutputStream()).thenReturn(oStream);

        PipedInputStream iStream = new PipedInputStream(oStream);
        when(mockTestClientSocket.getInputStream()).thenReturn(iStream);

        when(mockTestClientSocket.isClosed()).thenReturn(false);
    } catch (IOException e) {
        fail(e.getMessage());
    }
}
</code></pre>
<p>Part of what I'm trying to test is the following <code>run()</code> within an inner class which is kicked off in the <code>connection.listen()</code>:</p>
<pre><code>class InnerListenerClass implements Runnable {
    @Override
    public void run() {
        try {
            clientSocket = socket.accept();
            writer = new OutputStreamWriter(
               clientSocket.getOutputStream(), DEFAULT_CHARSETNAME);
            out = new PrintWriter(writer, true);
            while (!clientSocket.isClosed()) {
                out.println(&quot;Hello, world!&quot;);
                Thread.sleep(MILLIS_BETWEEN_MESSAGES);
            }
        } catch (InterruptedException | IOException e) {
            LOG.debug(e.getMessage());
        }
    }

    public InnerListenerClass(final ServerSocket socket) {
        this.socket = socket;
    } 
}
</code></pre>
<p>And here's a portion of the <code>TcpSocketConnection.java</code>:</p>
<pre><code>class TcpSocketConnection() {
    public TcpSocketConnection(final ServerSocket serverSocket) {
        checkNotNull(serverSocket);
        this.serverSocket = serverSocket;
    }
    ...
    public final void listen() throws IOException {
        listenerThread = new Thread(new InnerListenerClass(serverSocket));
        listenerThread.start();
    }
    ...
}
</code></pre>
<h1>How it works in my head</h1>
<p>I'm going to attempt to step through the process of my test to add some extra context to this question. Starting at the beginning of <code>testConnection()</code>:</p>
<pre><code>TcpSocketConnection connection = new TcpSocketConnection(mockServerSocket);
</code></pre>
<p>This creates a connection with a mocked ServerSocket associated with it. This creates a thread which kicks off with the following line:</p>
<pre><code>clientSocket = socket.accept();
</code></pre>
<p>since <code>socket</code> above is a reference to <code>mockServerSocket</code>, Mockito knows to return a reference to a mock Socket called <code>mockTestClientSocket</code> because of this line:</p>
<pre><code>when(mockServerSocket.accept()).thenReturn(mockTestClientSocket);
</code></pre>
<p>Next is the line below: <strong><em>NOTE: I believe this is where my understanding and reality diverge, as I believe based on debugging that this thread is hanging on creating this OutputStreamWriter object. I haven't figured out why.</em></strong></p>
<pre><code>writer = new OutputStreamWriter(clientSocket.getOutputStream(), DEFAULT_CHARSETNAME);
</code></pre>
<p>Make a new <code>OutputStreamWriter</code> given an <code>OutputStream</code>. Mockito knows what the output stream of the mocked client socket should look like because of these lines in the <code>setup</code> section:</p>
<pre><code>PipedOutputStream oStream = new PipedOutputStream();                 
when(mockTestClientSocket.getOutputStream()).thenReturn(oStream);
</code></pre>
<p>Also, because the <code>setup</code> happens before the test, we know that our InputStream has a reference to this OutputStream because of this line:</p>
<pre><code>PipedInputStream iStream = new PipedInputStream(oStream);
</code></pre>
<p>According to the documentation for this constructor, This <em>&quot;Creates a PipedInputStream so that it is connected to the piped output stream (oStream). Data bytes written to (oStream) will then be available as input from this stream.&quot;</em></p>
<p>The while loop in <code>run()</code> begins and causes &quot;Hello, world!&quot; to be sent out the OutputStream (and also received by the InputStream).
Next, we wrap up the inputStream nicely:</p>
<pre><code>BufferedReader reader = new BufferedReader(new InputStreamReader(mockTestClientSocket.getInputStream(), DEFAULT_CHARSET)); 
</code></pre>
<p>By the magic of Mockito, the <code>mockTestClientSocket.getInputStream()</code> call actually returns the <code>iStream</code> from earlier, because of the following line:</p>
<pre><code>when(mockTestClientSocket.getInputStream()).thenReturn(iStream);   
</code></pre>
<p>So now we have a reader with an input stream, and that input stream is hooked up to an output stream. That output stream is hooked up to a <code>PrintWriter</code> which is <code>println</code>ing &quot;Hello,world!&quot;s. However, the reader never seems to even get <code>ready()</code>.</p>
<h1>Question</h1>
<p><em>Why is the created listener thread hanging during creation of an <code>OutputStreamWriter</code>, and how can my <code>Hello, World!</code> string get sent properly from mocked socket to mocked client?</em></p>
<p>Apologies for being a Mockito/java.net.* newb and being a bit thick in general. I think I've included all the relevant portions of code, but if anything's unclear let me know.</p>