我正在尝试为我编写的 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/