Blocking calls are named that way because the execution waits until the call has finished. Most blocking calls just have to finish some processing without external interaction and then continue the execution con the caller.

But there are cases when the blocking call will not finish until an unblocking action has been done. Examples are: System.in.read(), new ServerSocket(0).accept()

The problem with testing blocking calls is that executing them in tests will block (obviously) them and not finish. No matter what, you’ll need at least two threads: one will get blocked and the other will do the unblocking action. Now, you can decide where to put those threads: in test code or in production code.

An example of doing it in tests from my http-server:

@Test
public void stopsWaitingForConnectionWhenAnotherThreadTellsToFinish()
            throws IOException, InterruptedException {
  server = new ServerSocket(9999);
  final ConnectionListener listener = new ConnectionListener(
      server,
      new NullConnectionHandler()
  );

  doAfterWaiting(50, new Action() { //Execute in another thread
      @Override
      public void run() {
          listener.finish(); //Unblocking from another thread
      }
  });

  listener.waitForConnection(); //Blocking call
}

...

public class ConnectionListener {
...
  public void waitForConnection() {
    ...

    Socket connection;
    try {
      connection = server.accept(); //Blocking call
    } catch (IOException e) {
      ...
    }
    ...
  }
}

Another example of doing it in code from my http-server

@Test
public void thePortIsUsedAfterStartingAndIsReleasedAfterStopping() {
  Server server = createServer(9999);
  server.start(); //Non-blocking call
  assertThat(isPortUsed(9999), is(true));
  server.stop();
  assertThat(isPortUsed(9999), is(false));
}

...

public class Server {
...
  public synchronized void start() {
  ...
    listener = new ConnectionListener(socket, connectionHandler);

    //Execute in another thread so this call does not block
    executor.execute(new Runnable() {
        @Override
        public void run() {
          while (!listener.isFinished())
            listener.waitForConnection(); //Blocking call
        }
    });
  }
}