QTimer timeout() signal not being called during unit test



  • I have a class that has a timeout in it which works fine while the regular application is running but when I do a unit test on the class the timeout() signal does not seem to be getting called. Any ideas on why it may not be work or why it is being blocked?

    This is equivalent to how I have my code setup

    @int main(int argc, char *argv[])
    {
    QCoreApplication app(argc, argv);

    QTest::qExec(myTestClass, argc, argv);

    while(1);
    }

    MyTestClass
    {
    ContentOfTestOne()
    {
    ConcreteClass testableClass;

    //Function is called and has a timeout in it set to 1 msec
    testableClass.DoFunctionWithTimeout();
    
    //I have a slot that will unlock the mWaitCondition once the timeout is emitted
    mMutex.lock();
    if(!mIsEventCalled)
    {
       mWaitCondition.wait(&mMutex, 1000);
    }
    mMutex.unlock();
    

    }

    }

    ConcreteClass
    {
    SetupTimer()
    {
    mpTimeoutTimer = new QTimer();

    mpTimeoutTimer->setInterval( 1 );
    
    mpTimeoutTimer->setSingleShot( true );
    
    connect(mpTimeoutTimer, SIGNAL( timeout() ), this, SLOT( OnTimeout() ) );
    

    }

    DoFunctionWithTimeout()
    {
    mpTimeoutTimer->start();
    }
    }@

    So I have the unit test calling the testable class which contains timer this should expire well before the wait condition. However, after the mpTimeoutTimer->start() is called it never goes into the OnTimeout slot. Is the WaitCondition in the unit test blocking the timer from emitting its signal? If so how to I correctly setup the unit test to allow for the timer to be called? I have my QCoreApplication executing its event loop from main so I didn't think any of the signals should be blocked at all. Also I have signals in other classes that I manually emit and those seem to work fine, however, the QTimer which I do not manually emit, seems to be blocked somehow.

    I have also tried adjusting my timers interval to 1000 msec to ensure that it wasn't too short for some reason, however, I still do not get a response on it.

    Any help would be appreciated.



  • QWaitCondition::wait is blocking, and doesn't allow the event loop needed by QTimer to run.

    A simple workaround would be to move the ConcreteClass along with the timer to a thread, so that it has its event loop.

    @ConcreteClass testableClass;

    QThread thread;
    thread.start();
    testableClass.moveToThread(thread);

    // the function is now in another thread, it can't be called directly anymore
    QMetaObject::invokeMethod(&testableClass, "DoFunctionWithTimeOut");

    mMutex.lock();
    if(!mIsEventCalled)
    {
    mWaitCondition.wait(&mMutex, 1000);
    }
    mMutex.unlock();

    thread.quit();
    thread.wait();
    @

    The timer should be made a child of the ConcreteClass to be moved to the other thread when the parent is moved.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.