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:
- Look into
SocketInputStream.java
source code, and I am confused how this snippet of code can simulate method block. Theread(temp, 0, 1)
leads to native methodsocketRead0
, 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 inC
?
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();
}
}