如何创建用于测试QTcpSocket的依赖项注入

How to create dependency injection for testing QTcpSocket?

本文关键字:QTcpSocket 依赖 注入 测试 用于 何创建 创建      更新时间:2023-10-16

我正试图为我编写的Qt5应用程序编写单元测试,但我对如何处理涉及网络的类感到困惑。我的主类包括一个QTcpServer子类,它覆盖QTcpServer::incomingConnection以创建ClientConnection对象并将其传递给线程:

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,我认为这是不可行的。

现在测试网络代码一定很常见,所以必须有一种通用的方法来处理它,而不包括我的一半应用程序。这似乎是一个一般性的问题,但如果需要更多关于我具体申请的细节,请告诉我。

首先,您可能希望为类定义干净的接口(意味着纯抽象类),这样模仿和交换它们就不会成为问题,比如IClientConnection

然后,您可以显式声明您的依赖项,即向NetworkServer构造函数传递IClientConnection工厂或IClientConnection实例。

在测试中,您现在可以实现IClientConnection的mock,并将其或其工厂(也可能是接口)传递给测试中的构造函数。也许,您可能想要使用智能指针(shared_ptr或Qt的原生指针),这样自动资源释放将最大限度地减少错误。

如果您的软件不断增长,并且您发现自己编写了大量手动依赖项注入,那么您可能会使用DI库。我最近开始审查一些可用的C++DI库。

最后,您可能会使用一个嘲讽框架(如googlemock)来嘲讽您的依赖关系,从而获得更大的成功。