3

私が書いた Qt5 アプリケーションの単体テストを作成しようとしていますが、ネットワークに関連するクラスを処理する方法について困惑しています。私のメイン クラスには、QTcpServer::incomingConnection をオーバーライドして ClientConnection オブジェクトを作成し、それをスレッドに渡す QTcpServer サブクラスが含まれています。

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 全体を作成しないと実現できないと思います。

最近はネットワーク コードのテストが一般的になっているはずなので、アプリケーションの半分を含めずにこれを処理する一般的な方法が必要です。これは一般的な質問のように思えますが、私の特定のアプリケーションに関する詳細が必要な場合はお知らせください。

4

1 に答える 1

1

First of all, you might want to define clean interfaces (meaning pure abstract classes) for your classes, so that mocking and exchanging them wouldn't be a problem, say IClientConnection.

Then, you could declare your dependencies explicitly, i.e. either pass an IClientConnection factory or an instance of an IClientConnection to the NetworkServer constructor.

In your test, you can now implement a mock of IClientConnection and pass it or its factory (may also be an interface) to the constructor in the test. Perhaps, you might want to use a smart pointer (shared_ptr or something native to Qt), so that automatic resource deallocation would minimize bugs.

If your software grows and you find yourself writing a lot of manual dependency injection, you might use a DI library. I've recently started a review of some of the available C++ DI libraries.

Finally, you might get far by mocking your dependencies using a mocking framework, such as googlemock.

于 2014-01-03T00:02:44.837 に答える