How to simulate method block similar to InputStream.read() until input data is available?

Viewed 121

My goal is to simulate ServerSocket communicating with Socket. However, I can't mimic the method blocks until input data is available of InputStream.read() using mockito.

My expected result: I can simulate method block if I call dis.readByte().

My actual result: thenCallRealMethod() will throw NullPointerException or thenReturn(-1) will throw EOFException.

What I've did:

  1. Look into SocketInputStream.java source code, and I am confused how this snippet of code can simulate method block. The read(temp, 0, 1) leads to native method socketRead0, so I can't read what inside this method. If you may, it would be nice if you are willing to spend time to explain how to read the native method. I use IntelliJ IDEA and rely on this key strokes CTRL+B or CTRL+SHIFT+B to help me see the source code, in this case pressing the CTRL+B or CTRL+SHIFT+B does not lead to the .c file. CMIIW based on this reference, I concluded that native method is a method that always written in C?

I found SocketInputStream.java by following the ServerSocket.accept() method and Socket.getInputStream().

SocketInputStream.java

    /**
     * Reads a single byte from the socket.
     */
    public int read() throws IOException {
        if (eof) {
            return -1;
        }
        temp = new byte[1];
        int n = read(temp, 0, 1);
        if (n <= 0) {
            return -1;
        }
        return temp[0] & 0xff;
    }

The test using mockito.

  @Test
  public void mockTest() {
    InputStream in = mock(InputStream.class);
    DataInputStream dis = new DataInputStream(in);
    try {
      when(in.read())
              .thenReturn(0x81)
              .thenReturn(0x82)
              .thenReturn(0x89)
              .thenReturn(0x8A)
              .thenReturn(0x88);
      // thenReturn simulate method block
    } catch (IOException e) {
      e.printStackTrace();
    }

    try {
      assertEquals(dis.readByte(), (byte) 0x81);
      assertEquals(dis.readByte(), (byte) 0x82);
      assertEquals(dis.readByte(), (byte) 0x89);
      assertEquals(dis.readByte(), (byte) 0x8A);
      assertEquals(dis.readByte(), (byte) 0x88);
      logger.debug(String.valueOf(dis.readByte())); // expected not to print nor throw EOFException.
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
0 Answers
Related