Single test sockets in java
I have a class that is a socket client and I am trying to unit test its methods. The tests require me to start the socket server before each test, so I use:
@Before
public void setUp() {
if (myServerSocket == null) {
Thread myThread = new Thread() {
public void run() {
DataInputStream dis = null;
DataOutputStream dos = null;
try {
ServerSocket myServer = new ServerSocket(port);
myServerSocket = myServer.accept();
dis = new DataInputStream(myServerSocket.getInputStream());
dos = new DataOutputStream(myServerSocket.getOutputStream());
byte[] bytes = new byte[10];
dis.read(bytes);
boolean breakLoop = false;
do {
if (new String(bytes).length() != 0) {
dos.writeBytes(serverMessage + "\n");
dos.flush();
breakLoop = true;
dos.writeBytes("</BroadsoftDocument>" + "\n");
dos.flush();
}
} while (!breakLoop);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
myThread.start();
}
}
After each test, I try to close the server socket so that I can reopen the server socket for the next test:
@After
public void tearDown() throws IOException, BroadsoftSocketException {
System.out.println("@After");
if (myServerSocket != null) {
myServerSocket.close();
myServerSocket = null;
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
// do nothing.
}
}
}
However, I get "java.net.BindException: address already in use: JVM_Bind" before every test starting with the second test. I understand that I am trying to use the same port for every test, but shouldn't I close the socket, freeing up the port?
source to share
It is possible that your socket is still in a state TIME_WAIT
when you try to reconnect it. I would recommend scoffing at such external dependencies, but if you really want to keep using a real socket try adjusting the rewrite options. In your setup function, instead of ServerSocket myServer = new ServerSocket(port);
doing:
final ServerSocket myServer = new ServerSocket();
myServer.setReuseAddress(true);
myServer.bind(new java.net.InetSocketAddress(port));
source to share
- You are already shutting down your backend in "setUp" and you really need to do it in a block
finally
. - The port cannot be released immediately. You can avoid this by setting the parameter to
ServerSocket
reuse address fortrue
. See setReuseAddress .
And I'm SimonC # 2: you might be better off avoiding the socket in the first place.
source to share