簡體   English   中英

如何測試內部創建和使用ServerSocket的方法

[英]How to test method that internally creates and uses a ServerSocket

我的服務器代碼如下所示:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server implements Runnable {   
    private ServerSocket serverSocket;
    public Server(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    @Override
    public void run() {
        try {
            Socket client = serverSocket.accept();
            // do stuff
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我的計划是編寫一個連接到服務器套接字的模擬客戶端,並驗證結果,但為此,我需要知道要連接到哪個端口。 但是,此信息是私人的。

我認為的所有選擇都不是良好實踐,我認為:

  1. 如果我使用預定義的端口號進行測試,則不能保證它將可用。 即使在測試之前就可以使用它,從理論上講,當我嘗試使用它時,它也會被搶走。
  2. 如果我將0用作端口號(以便ServerSocket原子地提供一個空閑端口),我仍然無法訪問它。
  3. 我可以在接口上添加getServerPort()方法,或者創建一個接受ServerSocket對象的構造函數,但是僅出於測試目的而更改接口被認為是不好的做法。

如所寫,您的課程並不真正適合單元測試。

問題是,直接調用new ServerSocket()基本上失去了控制套接字對象將要執行的操作的能力。

因此,您可以做什么:

interface SocketFactory {
  public ServerSocket createSocketFor(int port);
}

class SocketFactoryImpl implements SocketFactory {
...

public class Server implements Runnable {

  public Server(int port) {
    this(port, new SocketFactoryImpl());
  }

 Server(int port, SocketFactory socketFactory) {
   ...

換句話說:您使用依賴注入來為“被測類”提供均值,以創建需要其工作的對象。

從那里:你可以以控制什么嘲笑的SocketFactory對象將返回(可能是嘲笑 ServerSocket對象)使用模擬框架,如EasyMock的。 現在,您可以完全控制生產代碼使用的ServerSocket了……您可以測試所需的任何情況。

長話短說:不要叫新東西; 而是使用依賴注入來完全控制要測試的類。

(也許觀看這些視頻以真正了解編寫可測試代碼的含義)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM