c++ - 如何创建用于测试 QTcpSocket 的依赖注入(inject)?

标签 c++ qt dependency-injection qtestlib

我正在尝试为我编写的 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。我假设我需要使用某种依赖注入(inject),但我认为如果不在测试用例中创建整个 QTcpServer 是不可行的。

现在测试网络代码一定很常见,因此必须有一种通用的方法来处理这个问题,而无需包括我的一半应用程序。这似乎是一个一般性问题,但如果需要有关我的特定应用程序的更多详细信息,请告诉我。

最佳答案

首先,您可能想为您的类定义干净的接口(interface)(即 pure abstract classes ),这样模拟和交换它们就不会成为问题,例如 IClientConnection

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

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

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

最后,您可能会通过使用模拟框架来模拟您的依赖关系,例如 googlemock。 .

关于c++ - 如何创建用于测试 QTcpSocket 的依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20457748/

相关文章:

javascript - NestJS 在非模块文件中注入(inject)模块服务

c++ - 使用 boost 所有 linux 发行版编译 C++

qt - QGraphicsWidget如何实现点击事件?

c++ - 正则表达式奇怪的行为

c++ - Qt:如何在委托(delegate)绘制事件中渲染时增加 QTablewidget?

c# - 附加属性的统一

c# - Unity找不到部分类的构造函数

python - 无法构建使用 Python 的项目

c++ - OpenCV从矩阵获取条件库最大元素位置

c++ - 调整用户控件的大小