RequestProcessor class. This class reads request from input stream, does some processing, write response to output stream and closes the connection. public class RequestProcessor {
private Socket socket;
public RequestProcessor(Socket socket) {
this.socket = socket;
}
public void process() {
try {
InputStream is = socket.getInputStream();
String response = processRequest(is);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.append(response);
pw.flush();
} catch (IOException e) {
// catch exception
} finally {
try {
socket.close();
} catch (IOException e) {}
}
}
private String processRequest(InputStream is) {
// process request and send response
}
}
Here, we want to verify that in ideal case
RequestProcessor should first read request from socket.getInputStream() and then after processing request, write response in socket.getOutputStream(). One way that comes in mind is to write test as:@Test public void socketClosedInIdealCase() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream("a=b+c".getBytes());
when(socketMock.getInputStream()).thenReturn(bais);
when(socketMock.getOutputStream()).thenReturn(baos);
RequestProcessor request = new RequestProcessor(socketMock);
request.process();
// verify method invocations
verify(socketMock).getInputStream();
verify(socketMock).getOutputStream();
}
At first this test seems to be verifying what is suppose to, but unfortunately this test will not detect if
socket.getOutputStream() is moved before socket.getInputStream() as done in below code.public void process() {
try {
OutputStream os = socket.getOutputStream()
InputStream is = socket.getInputStream();
String response = processRequest(is);
// rest of the code
} catch (IOException e) {
// catch exception
} finally {
try {
socket.close();
} catch (IOException e) {}
}
}
}
This is because
Mockito.verify() static method only verifies whether any invocation happened on mock object. It does not verifies order of invocation. To make test verify invocation order, Mockito provides
Mockito.inOrder static method. Using this method above test can be rewritten as:@Test public void socketClosedInIdealCase() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream("a=b+c".getBytes());
when(socketMock.getInputStream()).thenReturn(bais);
when(socketMock.getOutputStream()).thenReturn(baos);
RequestProcessor request = new RequestProcessor(socketMock);
request.process();
// verify method invocations
InOrder order = inOrder(socketMock);
order.verify(socketMock).getInputStream();
order.verify(socketMock).getOutputStream();
}
If the order of invocation is changed in
RequestProcessor.process() method, this test will fail.Below is complete code.
No comments:
Post a Comment