2017-01-06 21 views
0

私は初めて私のプロジェクトに単体テストを追加しようとしています。QTユニットQMetaObjectのmoc "未解決の外部シンボル"をテストする

(プロジェクトのクラスを使わずに)モックテストを正常に実行して、アプリケーションを正常に実行できます。しかし、プロジェクトからオブジェクトをインスタンス化すると、QMetaObjectの未解決の外部シンボルが得られます。私が正しくリコールすれば、これはオブジェクトのモックがプロジェクトに含まれていないことを意味します。

これを修正するにはどうすればよいですか?私はgoogletestsを使用して同じ問題があります。ガイドはまた、これについて助けません。私は同じ結果をテストするプラグインをqtユニットをインストールしようとしました。

私は、私は前述のプロジェクトで使用している同じ構造を次のモックプロジェクトをアップロードし、ここでそれを取得しました:https://github.com/quimnuss/QtUnitTestingTest

私はWindows上でQTの静的ビルドを使用していますが、私は推測しますそれは無関係です。 IDEとしてQtCreatorを使用し、NMAkeをビルドします。

また、HelloWorld.libを追加しようとしましたが、Makefile.releaseを見てみると、使用されていません。

誰かが私が間違っていることを知っていますか?

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のあることを理解そのプロジェクトにはHelloWorldとMainWindowという2つのクラスがあります。なぜあなたが作成していないライブラリをリンクしたいのか分かりません。 HelloWorldクラスは一度も使用されていません。正確に何をテストしたいですか(HelloWorldクラスまたはMainWindowクラス)? – eyllanesc

+0

その模擬例では、 'HelloWorld'です。私は実際に 'true'を返す関数' returnsTrue'をテストしています。そのプロジェクトをビルドするとHelloWorld.libが作成されますが、ソースが存在するのでユニットテストに必要かどうかはわかりません。 – quimnuss

+0

.proにLIBS + = -lHelloWorldと書かれているので、ライブラリをビルドする必要がある場合。私はコードをアップロードする瞬間にテストを構築しました。 – eyllanesc

答えて

1

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

をあなたがコンパイルしている必要があります。ここ

は、ユニットテストは、.PROです動的または静的ライブラリ。したがって、ライブラリを生成するプロジェクトを作成する必要があります。次の部分では、動的ライブラリを作成する方法を示します。

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_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 
を含む/ 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 

を含みますここで

の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。

#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" 

をCPP出力:次のリンクで

********* 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 libがlib/release(gistの終わりを参照してください)に着いたので、そうでなければ見つからなくなるように私はwinスイッチを追加しなければなりませんでした。また、警告 'helloworldlib.obj:warning LNK4221:このオブジェクトファイルは以前定義されていないパブリックシンボルを定義しないので、ライブラリをビルドするときにはこのライブラリを使用するリンク操作では使用されません。 – quimnuss

+0

@quimnuss私の解決策を更新してください。動的ライブラリを静的ライブラリに変更する:https://github.com/eyllanesc/stackoverflow/tree/master/QtUnitTestingTest – eyllanesc

+0

優秀!これは機能します。私は月曜日にそれを勉強し、私のプロジェクトにそれを適応させます。優れた答え! – quimnuss

関連する問題