【问题标题】:unit testing sockets in javajava中的单元测试套接字
【发布时间】:2013-02-06 15:30:32
【问题描述】:

我有一个类是套接字客户端,我正在尝试对其方法进行单元测试。测试要求我在每次测试之前启动一个套接字服务器,所以我使用:

@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
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.
            }
    }
}

但是,在从第二个测试开始的每个测试之前,我都会收到“java.net.BindException:地址已在使用:JVM_Bind”。我意识到我正在尝试为每个测试使用相同的端口,但不应该关闭套接字以释放端口?

【问题讨论】:

  • 你真的需要连接到一个真实的套接字来测试你的代码吗?要测试套接字下游的代码,您可以将其抽象出来,以便传入一个 InputStream 和一个 OutputStream ,它们实际上是从您的单元测试中写入/读取的。
  • 我以前在单元测试中看到过套接字。结局并不好——很多随机失败。特别是添加了 sleep(5000) 等延迟,因为不同人的机器在关闭套接字时会更慢。有没有办法重构类,使其“SocketClient”部分与其“可测试”逻辑部分分开?测试底层的 java Socket 代码没有任何好处——我们知道这是可行的。您只想对生成消息的代码位进行单元测试。

标签: java sockets


【解决方案1】:

当您尝试重新连接时,您的套接字很可能仍处于TIME_WAIT 状态。我建议模拟这种外部依赖项,但如果您确实发现自己想要继续使用真正的套接字,那么请尝试设置重新绑定选项。在您的设置功能中,而不是 ServerSocket myServer = new ServerSocket(port); 做:

final ServerSocket myServer = new ServerSocket();
myServer.setReuseAddress(true);
myServer.bind(new java.net.InetSocketAddress(port));

【讨论】:

    【解决方案2】:
    1. 您已经在“setUp”中关闭了服务器套接字,您确实应该在 finally 块中关闭。
    2. 端口可能不会立即释放。您可以通过将ServerSocket 的reuseAdress 设置为true 来避免这种情况。见setReuseAddress

    我第二个 SimonC:也许你最好一开始就避开套接字。

    【讨论】:

      猜你喜欢
      • 2011-05-31
      • 2011-07-31
      • 1970-01-01
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2020-02-05
      相关资源
      最近更新 更多