派生 class 中的虚函数在使用 GoogleTest 进行测试时未被调用
virtual function in derived class not getting called when testing with GoogleTest
我在使用 GoogleTest 调用我在派生 class 中定义的虚函数时遇到问题。
我使用派生自 QTcpServer 的 Qt 创建了一个 class MyServer。当我 运行 此代码在 GoogleTest 之外时,程序会按预期运行。当我在 class 中使用 GoogleTest incomingConnection 创建项目时,永远不会被调用。套接字被接受,就好像 QTcpServer::incomingConnection 收到呼叫一样。
MyThread 将发出信号 ReadySocket(),该信号通常连接到创建 MyServer 的任何人。测试时,我创建了一个 MyServerTester Class,它将接收信号并设置一个我可以断言的标志。
我可以将问题简化为以下代码 在 incomingConnection 中设置断点,启动服务器,使用客户端连接到它。连接将被接受,MyServer::incomingConnection 将不会进入,因此永远不会创建 MyThread。
项目:服务器File:MyServer.h
class MyServer : public QTcpServer
{
Q_OBJECT
public:
MyServer(QObject *parent = 0);
protected:
void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
}
项目:服务器File:MyServer.cpp
#include "MyServer.h"
MyServer::MyServer(QObject *parent) : QTcpServer(parent) { }
void MyServer::incomingConnection(qintptr socketDescriptor)
{
MyThread *thread = new MyThread(socketDescriptor, this);
connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
}
项目:Server_Test File:main.cpp
#include <QtCore/QCoreApplication>
#include "gtest\gtest.h"
#include "..\Server\MyServer.h"
TEST(MyServer, Successful_Connection)
{
MyServer server;
server.listen(QHostAddress::AnyIPv4, 4444);
QThread::sleep(30);
}
int main(int argc, char*argv[])
{
QCoreApplication a(argc, argv);
::testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
return a.exec()
}
问题是您的 server
对象在 TEST
结束后被销毁。
可以试试
QTcpServer *server;
TEST(MyServer, Successful_Connection)
{
server = new MyServer;
server->listen(QHostAddress::AnyIPv4, 4444);
QThread::sleep(30);
}
并在 TEST
完成后删除 server
。
首先观察到这些不是单元测试,而是更多的集成测试,因为它们使用网络和 Qt 事件循环。
问题是您正在测试需要 Qt 事件循环(a.exec()
调用)为 运行 的 Qt 信号。但是在你的 main
中,你实际上是 运行 开始事件循环之前的测试。我不确定是否值得尝试在 gtest 中插入 Qt 事件循环。
我建议另一种方法:使用 Qt Test,它非常适合 Qt 事件循环,例如,有一个非常方便的信号间谍来验证信号传播。
我在使用 GoogleTest 调用我在派生 class 中定义的虚函数时遇到问题。
我使用派生自 QTcpServer 的 Qt 创建了一个 class MyServer。当我 运行 此代码在 GoogleTest 之外时,程序会按预期运行。当我在 class 中使用 GoogleTest incomingConnection 创建项目时,永远不会被调用。套接字被接受,就好像 QTcpServer::incomingConnection 收到呼叫一样。
MyThread 将发出信号 ReadySocket(),该信号通常连接到创建 MyServer 的任何人。测试时,我创建了一个 MyServerTester Class,它将接收信号并设置一个我可以断言的标志。
我可以将问题简化为以下代码 在 incomingConnection 中设置断点,启动服务器,使用客户端连接到它。连接将被接受,MyServer::incomingConnection 将不会进入,因此永远不会创建 MyThread。
项目:服务器File:MyServer.h
class MyServer : public QTcpServer
{
Q_OBJECT
public:
MyServer(QObject *parent = 0);
protected:
void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
}
项目:服务器File:MyServer.cpp
#include "MyServer.h"
MyServer::MyServer(QObject *parent) : QTcpServer(parent) { }
void MyServer::incomingConnection(qintptr socketDescriptor)
{
MyThread *thread = new MyThread(socketDescriptor, this);
connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
}
项目:Server_Test File:main.cpp
#include <QtCore/QCoreApplication>
#include "gtest\gtest.h"
#include "..\Server\MyServer.h"
TEST(MyServer, Successful_Connection)
{
MyServer server;
server.listen(QHostAddress::AnyIPv4, 4444);
QThread::sleep(30);
}
int main(int argc, char*argv[])
{
QCoreApplication a(argc, argv);
::testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
return a.exec()
}
问题是您的 server
对象在 TEST
结束后被销毁。
可以试试
QTcpServer *server;
TEST(MyServer, Successful_Connection)
{
server = new MyServer;
server->listen(QHostAddress::AnyIPv4, 4444);
QThread::sleep(30);
}
并在 TEST
完成后删除 server
。
首先观察到这些不是单元测试,而是更多的集成测试,因为它们使用网络和 Qt 事件循环。
问题是您正在测试需要 Qt 事件循环(a.exec()
调用)为 运行 的 Qt 信号。但是在你的 main
中,你实际上是 运行 开始事件循环之前的测试。我不确定是否值得尝试在 gtest 中插入 Qt 事件循环。
我建议另一种方法:使用 Qt Test,它非常适合 Qt 事件循环,例如,有一个非常方便的信号间谍来验证信号传播。