2017-01-06 46 views
0

我試圖首次將單元測試添加到我的項目中。QT單元測試用於QMetaObject的moc「無法解析的外部符號」

我可以運行模擬測試好嗎(無需使用我的項目類)並運行應用程序好吧。但是如果我從項目中實例化對象,我會得到一個未解析的QMetaObject的外部符號。如果我沒有記錯,這意味着該對象的moc未包含在該項目中。

我該如何解決這個問題?我有使用googletests相同的問題。該指南對此也沒有幫助。我試過安裝qt單元測試插件,結果相同。

我上傳下面,我使用在上述項目中的相同結構的模擬項目,在這裏把它拿來:https://github.com/quimnuss/QtUnitTestingTest

我在Windows上使用QT的靜電積累,但我猜這是不相干的。使用QtCreator作爲IDE和NMAke構建。

我也嘗試添加HelloWorld.lib,但看看Makefile.release它沒有使用。

有人對我做錯了什麼想法?

這裏的單元測試的.pro:

QT  += widgets network testlib 

TARGET = tst_someunittesttest 
CONFIG += console 
CONFIG -= app_bundle 

TEMPLATE = app 

INCLUDEPATH += $$PWD/../HelloWorld 

include($$PWD/../HelloWorld/helloworldCommon.pri) 

LIBS += -L"$$OUT_PWD/../HelloWorld/release" 
LIBS += -lHelloWorld 

message("Searching libs here $$LIBS") 

SOURCES += tst_someunittesttest.cpp 
DEFINES += SRCDIR=\\\"$$PWD/\\\" 

的第一個錯誤的完整信息:

tst_someunittesttest.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl HelloWorld::metaObject(void)const " ([email protected]@@[email protected]@XZ) 
+0

我查閱了您的項目,我知道你要測試的項目的HelloWorld,內該項目有2個類:HelloWorld和MainWindow。我不明白你爲什麼要鏈接一個你還沒有創建的庫。除了HelloWorld類從未使用過。究竟你想測試什麼(HelloWorld類或MainWindow類)? – eyllanesc

+0

在這個模擬的例子中,'HelloWorld'。我正在測試'returnsTrue'函數,它確實返回'true'。構建該項目會創建HelloWorld.lib,儘管我不確定是否需要進行單元測試,因爲源代碼仍然存在。 – quimnuss

+0

如果有必要構建庫,因爲在.pro中寫入LIBS + = -lHelloWorld。我已經在一段時間內完成了測試,我將上傳代碼。 – eyllanesc

回答

1

當您使用以下標誌:

LIBS += -L"$$OUT_PWD/../HelloWorld/release" 
LIBS += -lHelloWorld 

您必須編譯動態或靜態庫。因此您必須創建一個生成庫的項目。在下一部分中,我向您展示如何創建一個動態庫。

HelloWorldLib.pro

#------------------------------------------------- 
# 
# Project created by QtCreator 2017-01-06T12:37:49 
# 
#------------------------------------------------- 

QT  -= gui 

TARGET = HelloWorldLib 
TEMPLATE = lib 

DEFINES += HELLOWORLDLIB_LIBRARY 

# The following define makes your compiler emit warnings if you use 
# any feature of Qt which as been marked as deprecated (the exact warnings 
# depend on your compiler). Please consult the documentation of the 
# deprecated API in order to know how to port your code away from it. 
DEFINES += QT_DEPRECATED_WARNINGS 

# You can also make your code fail to compile if you use deprecated APIs. 
# In order to do so, uncomment the following line. 
# You can also select to disable deprecated APIs only up to a certain version of Qt. 
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 

INCLUDEPATH += $$PWD/include 

SOURCES += src/helloworldlib.cpp 

HEADERS += include/helloworldlib.h\ 
     include/helloworldlib_global.h 

unix { 
    target.path = /usr/lib 
    INSTALLS += target 
} 

DESTDIR = $$PWD/lib 

包括/ helloworldlib.h

#ifndef HELLOWORLDLIB_H 
#define HELLOWORLDLIB_H 

#include "helloworldlib_global.h" 

#include <QDebug> 

class HELLOWORLDLIBSHARED_EXPORT HelloWorldLib: public QObject 
{ 
    Q_OBJECT 

public: 
    HelloWorldLib(){ 

    } 
    static bool returnTrue() 
    { 
     return true; 
    } 

public slots: 
    void someSlot() 
    { 
     qDebug() << "test"; 
    } 
}; 

#endif // HELLOWORLDLIB_H 

包括/ helloworldlib_global.h

#ifndef HELLOWORLDLIB_GLOBAL_H 
#define HELLOWORLDLIB_GLOBAL_H 

#include <QtCore/qglobal.h> 

#if defined(HELLOWORLDLIB_LIBRARY) 
# define HELLOWORLDLIBSHARED_EXPORT Q_DECL_EXPORT 
#else 
# define HELLOWORLDLIBSHARED_EXPORT Q_DECL_IMPORT 
#endif 

#endif // HELLOWORLDLIB_GLOBAL_H 

的src/helloworldlib.cpp

#include "helloworldlib.h" 

在這裏,我展示了測試項目。

HelloWorldTest.pro

#------------------------------------------------- 
# 
# Project created by QtCreator 2017-01-06T12:42:42 
# 
#------------------------------------------------- 

QT += testlib 
QT -= gui 

# greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 

TARGET = tst_helloworldtesttest 
CONFIG += console 
CONFIG -= app_bundle 

TEMPLATE = app 

# The following define makes your compiler emit warnings if you use 
# any feature of Qt which as been marked as deprecated (the exact warnings 
# depend on your compiler). Please consult the documentation of the 
# deprecated API in order to know how to port your code away from it. 
DEFINES += QT_DEPRECATED_WARNINGS 

# You can also make your code fail to compile if you use deprecated APIs. 
# In order to do so, uncomment the following line. 
# You can also select to disable deprecated APIs only up to a certain version of Qt. 
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 


SOURCES += tst_helloworldtesttest.cpp 
DEFINES += SRCDIR=\\\"$$PWD/\\\" 

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../HelloWorldLib/lib/release/ -lHelloWorldLib 
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../HelloWorldLib/lib/debug/ -lHelloWorldLib 
else:unix: LIBS += -L$$PWD/../HelloWorldLib/lib/ -lHelloWorldLib 

INCLUDEPATH += $$PWD/../HelloWorldLib/include 
DEPENDPATH += $$PWD/../HelloWorldLib/include 

tst_helloworldtesttest。CPP

#include <QString> 
#include <QtTest> 

#include <helloworldlib.h> 

#include <QDebug> 

class HelloWorldTestTest : public QObject 
{ 
    Q_OBJECT 

public: 
    HelloWorldTestTest(); 

private Q_SLOTS: 
    void testCase1_data(); 
    void testCase1(); 
}; 

HelloWorldTestTest::HelloWorldTestTest() 
{ 
} 

void HelloWorldTestTest::testCase1_data() 
{ 
    QTest::addColumn<QString>("data"); 
    QTest::newRow("0") << QString(); 
} 

void HelloWorldTestTest::testCase1() 
{ 
    QFETCH(QString, data); 
    QVERIFY2(true, "Failure"); 

    HelloWorldLib hw; 
    QVERIFY(hw.returnTrue()); 

} 

QTEST_APPLESS_MAIN(HelloWorldTestTest) 

#include "tst_helloworldtesttest.moc" 

輸出:

********* Start testing of HelloWorldTestTest ********* 
Config: Using QtTest library 5.7.1, Qt 5.7.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 6.2.1 20160830) 
PASS : HelloWorldTestTest::initTestCase() 
PASS : HelloWorldTestTest::testCase1(0) 
PASS : HelloWorldTestTest::cleanupTestCase() 
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms 
********* Finished testing of HelloWorldTestTest ********* 

在下面的環節是完整的項目:https://github.com/eyllanesc/stackoverflow/tree/master/QtUnitTestingTest

+0

感謝您的完整解決方案!超過我的預期。我也有一個未定義的符號,好像它忽略了lib。輸出錯誤:https://gist.github.com/quimnuss/ce638019cfd5abb3572e761761bdb47f 我不得不添加一個win開關,以便lib在lib/release下(見要點的結尾),否則它甚至不會找到它。另外,我得到一個警告'helloworldlib.obj:警告LNK4221:這個目標文件沒有定義任何先前未定義的公共符號,所以當我僅構建庫時,它不會被任何使用這個庫的鏈接操作使用。 – quimnuss

+0

@quimnuss更新我的解決方案。將動態庫更改爲靜態庫:https://github.com/eyllanesc/stackoverflow/tree/master/QtUnitTestingTest – eyllanesc

+0

優秀!這工作。我會在星期一進行研究並將其應用於我的項目。優秀的答案! – quimnuss