我已经实现了一个 RMI 服务器,现在我想使用 JUnit 测试来测试启动和停止该服务器的方法是否正确实现。
这是我的 RMI 服务器的(简化)代码:
public void startServer() {
try {
...
registry = LocateRegistry.createRegistry(serverPort);
registry.rebind("foobar", myRemoteObject);
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopServer() {
try {
registry.unbind("foobar");
} catch (Exception e) {
e.printStackTrace();
}
}
现在,我想做一个 JUnit 测试来检查startServer()
和stopServer()
是否正常工作。
因此,我实现了这个简单的 JUnit 测试:
private boolean isRunning(int port) {
boolean portTaken = false;
ServerSocket socket = null;
try {
socket = new ServerSocket(port);
// If we have succesfully created the ServerSocket, then it means that the port is available...
} catch (IOException e) {
portTaken = true;
if (socket != null) {
try {
socket.close();
} catch (IOException e2) {
}
}
}
return portTaken;
}
@Test
public void testStartAndStopServer() {
MyRMIServer server = new MyRMIServer();
assertNotNull(server);
int port = server.getServerPort();
assertTrue(port != -1);
// Check if the current server is NOT running.
assertFalse(isRunning(port));
// Start the server and then check if it is running.
server.startServer();
assertTrue(isRunning(port));
// Now stop the server...
server.stopServer();
assertFalse(isRunning(port));
}
我的问题是最后一个断言无效。如果我在方法中打印堆栈跟踪,则会isRunning()
收到错误消息java.net.BindException: Address already in use: JVM_Bind
。
这意味着该端口仍在使用,所以我猜我stopServer()
的不正确。我做错了什么?
请注意,如果我registry.list()
在调用我的方法之前和之后使用该方法stopServer()
,我会看到:
BEFORE: foobar
AFTER: (nothing)
编辑:
我还修改了stopServer()
关于此处解释的解决方案:
public void stopServer() {
try {
registry.unbind("foobar");
UnicastRemoteObject.unexportObject(myRemoteObject, true);
} catch (Exception e) {
e.printStackTrace();
}
}
但这并不能解决我的问题...