Search code examples
c++qtgoogletestgooglemocklnk2019

LNK2019 With Qt and Gmock


I've been banging my head against the wall on this one for the past few days. I am trying to incorporate googletest's gmock library into my Qt Autotest subdir project, but have been receiving the following linker error and I am unsure on how to resolve this. The main application compiles and runs perfectly fine.

tst_reptileprofile.obj : error LNK2019: unresolved external symbol "public: __thiscall DashboardWidget::DashboardWidget(void)" (??0DashboardWidget@@QAE@XZ) referenced in function "private: void __thiscall TestReptileProfile::init(void)" (?init@TestReptileProfile@@AAEXXZ)

Here is the test code:

#include <QtTest/QtTest>
#include <QCoreApplication>
#include <QObject>
#include "gmock/gmock.h"

#include "../Application/dashboardwidget.h"

class TestReptileProfile : public QObject
{
    Q_OBJECT

public:
    TestReptileProfile() {}
    ~TestReptileProfile() {}

private slots:
    void initTestCase()
    {
    }
    void cleanupTestCase()
    {
    }

    void init()
    {
        dashboard_ = new DashboardWidget();
    }

    void cleanup()
    {
        delete dashboard_;
    }

private:
    DashboardWidget* dashboard_;

};

#include "tst_reptileprofile.moc"
QTEST_MAIN(TestReptileProfile)

DashboardWidget.h/.cpp

#pragma once

#include <QtWidgets/QWidget>
#include <QtWidgets/QAbstractButton>

namespace Ui {
class DashboardWidget;
}

class DashboardWidget : public QWidget
{
    Q_OBJECT

public:
    explicit DashboardWidget();
    ~DashboardWidget();
    QAbstractButton* openProfileButton();

private:
    Ui::DashboardWidget *ui;
    QAbstractButton* openProfileButton_;
};

#include "dashboardwidget.h"
#include "ui_dashboardwidget.h"

DashboardWidget::DashboardWidget() :
    ui(new Ui::DashboardWidget)
{
    ui->setupUi(this);
    openProfileButton_ = ui->openReptileProfilePageButton;
}

DashboardWidget::~DashboardWidget()
{
    delete ui;
}

QAbstractButton* DashboardWidget::openProfileButton()
{
    return openProfileButton_;
}

Subdirs Project .pro

TEMPLATE = subdirs

CONFIG += ordered

SUBDIRS += \
    Application \
    AutoTests

AutoTests.depends = Application

Application.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Application
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp \
        mainview.cpp \
        . . .
    mainpresenter.cpp \
    dashboardwidget.cpp \


FORMS += \
        mainview.ui \
    i_mainpresenter.h \
    dashboardwidget.ui \

HEADERS += \
        mainview.h \
    dashboardwidget.h \

AutoTests.pro

QT += testlib
QT += gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += qt warn_on depend_includepath testcase

TEMPLATE = app

SOURCES += \ 
    tst_reptileprofile.cpp

unix|win32: LIBS += -L$$PWD/../../../googletest/googlemock/msvc/2015/Win32-Release/ -lgmock

INCLUDEPATH += $$PWD/../../../googletest/googlemock/msvc/2015/Win32-Release
DEPENDPATH += $$PWD/../../../googletest/googlemock/msvc/2015/Win32-Release

INCLUDEPATH += D:\googletest\googlemock\include\
INCLUDEPATH += D:\googletest\googletest\include\

I also tried converting the project into a Visual Studio project which causes a compilation error instead.

Error   C2059   syntax error: '.'   AutoTests   ProjectDir\tst_reptileprofile.cpp   63  

Thanks


Solution

  • There are two points. The first thing: you are creating two executables (application and AutoTest). To test your production code you have to build it into a library.

    TEMPLATE = lib
    

    That means, one should create two executables, for testing and for the application. The executables need to be linked against the new library. e.g:

    LIBS += -L../lib/debug -llib
    

    At the end you have three subdirectories and .pro-files.

    The second thing: The symbols in the library has to be exported if the library is created and imported when you are linking against the library. This can be done with the preprocessor definition: TEST_COMMON_DLLSPEC.

    You find the complete how to in the following link: https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application

    This tutorial isn't with googletest but you can use it similar.