c++qtunit-testingqtimerqttest

Disconnect qt timer for unit test


I'm trying to unit test some legacy code which is using QTimer for some periodic action basically:

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject* parent = nullptr) : QObject(parent)
    {
        timer.setInterval(1000);
        timer.setSingleShot(false);
        timer.start();
        connect(&timer, &QTimer::timeout, this, &MyClass::onTimeout);
    }
    int getValue() const
    {
        return value;
    }
signals:

public slots:
    void onTimeout()
    {
        value++;
    }
private:
    int value{0};
    QTimer timer{this};
};

I need to write unit test for the method onTimeout() hence I'm trying to disconnect the QTimer::timeout from MyClass::onTimeout and trigger the update from the unit test.

void testFirstUpdate()
{
    MyClass myClass;
    qDebug() << "disconnect: " << myClass.disconnect(); //returns false
    myClass.dumpObjectInfo();
    QCOMPARE(myClass.getValue(), 0);
    myClass.onTimeout();
    QCOMPARE(myClass.getValue(), 1);
}

How can I make the disconnect working? Or is there a better way controlling QTimer from QtTestLib? Is adding MyClass::disconnectTimer() the only viable option?


Solution

  • An alternative solution may be to make a new thread and move MyClass to it. Since you will not start the new thread there will be no event loop to catch the timeout function. Moving myClass will cause the timer to restart but since the event loop of the new thread isn't running the timeout signal will never fire.

    QThread t;
    myClass.moveToThread(&t);
    

    I take it you cannot edit the "legacy" code, refactoring the legacy code to be unit testable would be the best solution.