2013-12-08 78 views
2

我正在編寫我編寫的Qt5應用程序的單元測試,但是我很難理解如何處理涉及網絡的類。我的主類包括QTcpServer既可子類,它覆蓋QTcpServer既可:: incomingConnection創建ClientConnection對象並把它開了一個主題:如何創建用於測試QTcpSocket的依賴注入?

void NetworkServer::incomingConnection(qintptr socketDescriptor) 
{ 
    QThread* clientThread = new QThread(); 
    ClientConnection* clientConnection = new ClientConnection(socketDescriptor); 
    clientConnection->moveToThread(clientThread); 

    // connect signals & slots to ClientConnection (removed for clarity) 

    connect(clientThread, &QThread::started, clientConnection, &ClientConnection::run); 
    clientThread->start(); 
} 

的ClientConnection類使用socketDescriptor在專用線程中打開一個新的與QTcpSocket,從客戶端接收數據並對其進行處理。

ClientConnection::ClientConnection(int socketDescriptor, QObject *parent) : 
    QObject(parent), socketDescriptor(socketDescriptor) 
{ 
    tcpIncomingData = new QByteArray; 
} 

void ClientConnection::run() 
{ 
    QTcpSocket socket; 
    if(!socket.setSocketDescriptor(socketDescriptor)) { 
      emit sig_error(socket.error()); 
      return; 
     } 

    if(socket.waitForReadyRead(5000)) { 
     *tcpIncomingData = socket.readAll(); 
     qDebug() << "data received: " << tcpIncomingData; 
    } else { 
     qDebug() << "socket timed out!"; 
    } 

    parseXmlData(); 

    socket.disconnectFromHost(); 
    socket.waitForDisconnected(); 
} 

該課程尚未完成,但我現在要開始編寫測試。我的問題是如何處理socketDescriptor。我假設我需要使用某種依賴注入,但如果不在測試用例中創建一個完整的QTcpServer,我認爲這是不可行的。

現在測試網絡代碼必須是通用的,所以必須有一個通用的方法來處理這個問題,而不包括我的一半應用程序。這似乎是一個普遍的問題,但如果需要更多關於我的具體應用的細節,請告訴我。

回答

1

首先,您可能想要爲您的類定義乾淨的接口(意爲pure abstract classes),以便嘲笑和交換它們不會成爲問題,例如IClientConnection

然後,您可以明確聲明您的依賴關係,即將IClientConnection工廠或IClientConnection的實例傳遞給NetworkServer構造函數。

在您的測試中,您現在可以實現IClientConnection的模擬並將其或工廠(也可以是接口)傳遞給測試中的構造函數。也許,你可能想要使用一個智能指針(shared_ptr或Qt的本地特性),這樣自動資源釋放可以最大限度地減少錯誤。

如果您的軟件增長並且您發現自己編寫了大量手動依賴注入,則可以使用DI庫。我最近開始使用一些可用的C++ DI庫的review

最後,使用模擬框架(例如googlemock)嘲笑您的依賴關係可能會讓您感到茫然。

+0

p.s.你有沒有考慮過使用更高層次的網絡組件? –