如何创建用于测试QTcpSocket的依赖项注入
How to create dependency injection for testing QTcpSocket?
我正试图为我编写的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)来嘲讽您的依赖关系,从而获得更大的成功。
- 如何从C++中的依赖类型中获得它所依赖的类型
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 将依赖名称显式标记为类型名和模板的奇怪之处
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- C++GTKMM gui循环依赖关系
- 通过ccmake在cmake中缓存依赖选项
- QTcpSocket在不阻塞GUI的情况下重新连接到服务器
- 当基类是依赖类型时,这是一个缺陷吗
- 从不同的附加依赖项中识别等同命名的函数
- 如何在 CMake 中对目标依赖项进行分组?
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 为什么构建目录中新构建的共享库与安装目录中的副本具有不同的依赖项集?
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 为什么内存屏障依赖于变量?
- node-gyp 的先有鸡还是先有蛋的问题:指向依赖项中的头文件
- 反转依赖于 end() 的迭代器
- 如何使用 QDatastream 通过 QTcpSocket 发送 QSqlQueryModel?
- GCC,CMake,预编译标头和维护依赖项
- 如何创建用于测试QTcpSocket的依赖项注入