I think it's possible to test this method with another threads and some helper code which passes fix requests to your server and checks the server's answer. It definitely requires some work and I'm not sure how should we call this test: unit test, module test or integration test? Anyway, make sure that the checks happens on the the test method's thread, otherwise JUnit won't detect the uncatched exceptions.
To make it more testable I'd separate the ClientManager
creation to an IncomingConnectionHandler
interface and implementation and pass an instance of this object to the class of the listen
method.
public interface IncomingConnectionHandler {
void handle(Socket socket);
}
public final class IncomingConnectionHandlerImpl {
public IncomingConnectionHandlerImpl {
}
public void handle(final Socket socket) {
final ClientManager client = new ClientManager(clientSocket);
client.start();
}
}
public class MySocketListener {
private final IncomingConnectionHandler incomingConnectionHandler;
public MySocketListener(final IncomingConnectionHandler incomingConnectionHandler) {
this.incomingConnectionHandler = checkNotNull(incomingConnectionHandler,
"incomingConnectionHandler cannot be null");
}
public void listen() {
try {
serverSocket = new ServerSocket(portNo);
while (true) {
final Socket clientSocket = serverSocket.accept();
incomingConnectionHandler.handle(clientSocket);
}
} catch (Exception e) {
//handle any exceptions
} finally {
close(); //close any open sockets
}
}
After this in the unit test you could do the following:
- create a
MySocketListener
instance with a mocked IncomingConnectionHandler
,
- start an new thread which connects to the port of
MySocketListener
,
- check that the handle method of the mocked
IncomingConnectionHandler
was called with a live/proper Socket
instance,
- shutdown the helper thread and the
MySocketListener
.
Consider not using using abbreviation like Mgr
. It would make the code readable.