Sas*_*asa 19 c++ qt unit-testing
是否可以在同一.cpp文件中进行类声明和实现?
我想借助mock对象做一些单元测试.以下是我测试的一些示例:
// Some includes removed
#include "abstractconnection.h"
class ConnectionMockup : public AbstractConnection
{
Q_OBJECT
public:
explicit ConnectionMockup(QObject *parent = 0);
bool isReady() const;
void sendMessage(const QString &message);
void test_send_message(const QString &message);
bool ready;
QStringList messages;
};
ConnectionMockup::ConnectionMockup(QObject *parent)
: AbstractConnection(parent)
{
ready = true;
}
bool ConnectionMockup::isReady() const
{
return ready;
}
void ConnectionMockup::sendMessage(const QString &message)
{
messages.append(message);
}
void ConnectionMockup::test_send_message(const QString &message)
{
emit messageRecieved(message);
}
TestEmcProgram::TestEmcProgram(QObject *parent) :
QObject(parent)
{
}
void TestEmcProgram::open()
{
ConnectionMockup mockup;
EmcProgram program(&mockup);
QCOMPARE(...
...
...
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,ConnectionMockup类仅由类TestConnection使用,我在其他任何地方都不需要它.所以,当我尝试编译这个程序时,我得到以下错误:
> testemcprogram.o: In function
> `ConnectionMockup':
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:29:
> undefined reference to `vtable for
> ConnectionMockup'
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:29:
> undefined reference to `vtable for
> ConnectionMockup' testemcprogram.o: In
> function `~ConnectionMockup':
> /home/sasa/Desktop/QtPro/FocoKernel-build-desktop/../FocoKernel/testemcprogram.cpp:14:
> undefined reference to `vtable for
> ConnectionMockup'
Run Code Online (Sandbox Code Playgroud)
是否可以在此处留下声明,或者我必须创建头文件并将声明移入该文件?
编辑:由于Jerry Coffin先生(谢谢Coffin先生)建议我可能没有实现一些虚函数,我将在这里声明AbstractConnection,以便我们可以审查这种可能性:
#include <QObject>
class AbstractConnection : public QObject
{
Q_OBJECT
public:
explicit AbstractConnection(QObject *parent = 0);
virtual ~AbstractConnection();
virtual bool isReady() const = 0;
signals:
void messageRecieved(const QString &message);
public slots:
virtual void sendMessage(const QString &message) = 0;
};
Run Code Online (Sandbox Code Playgroud)
解决方案:感谢@JCooper,@ immilind和@Jerry Coffin我们有解决方案.从AbstractConnection中删除析构函数后(因为它实际上什么都不做)并从ConnectionMockup中删除Q_OBJECT它可以工作.
Ele*_*rks 18
的Q_OBJECT宏声明一组元对象的成员函数.MOC构建工具负责解析.h文件并定义这些函数声明.请注意,它不解析.cpp文件.在您的情况下,vtable无法找到,因为MOC工具没有解析您的.cpp文件.解决方案是将类定义移到头文件中,并将头添加到.pro文件中.第二个解决方案 - 有点"hacky" - 是做以下事情:
#include <QObject>
#include <QtDebug>
class Counter : public QObject
{
Q_OBJECT
public:
Counter() { value = 0; }
int getValue() const { qDebug() << "getValue()"; return value; }
public slots:
void setValue(int value);
signals:
void valueChanged(int newValue);
private:
int value;
};
#include "main.moc"
void Counter::setValue(int value)
{
qDebug() << "setValue()";
if (this->value != value) {
this->value = value;
emit valueChanged(value);
}
}
int main()
{
Counter a, b;
QObject::connect(
&a, &Counter::valueChanged,
&b, &Counter::setValue);
a.setValue(12);
b.setValue(48);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
注意类定义下的`#include"myfile.moc".
这是有效的,因为qmake将使用#include指令在任何文件上调用MOC工具.因此,MOC将解析.cpp文件并生成元对象函数定义,从而解决链接器错误.
Jer*_*fin 14
是的,完全合法且允许在单个文件中定义类及其成员函数.实际上,从编译器的角度来看,实际上总是如此 - 您在头文件中有类定义,并在源文件中包含该头,您实现其成员函数.
您遇到的错误看起来像链接器错误,而不是编译器错误.究竟缺少什么并不完全清楚你发布的内容.一种可能性是,你的基类有你未能在派生类中实现一些是纯虚函数,但我不都确信这是正确的.