Pregunta

I'm trying to test a QObject based class with will emit signals asynchronously (actually from a background thread).

I saw a post here about doing this:

https://groups.google.com/forum/#!topic/googlemock/RTgynKPa6ew

Which linked to this source code:

http://www.etotheipiplusone.com/projects/qsignalmock/qsignalmock.cpp http://www.etotheipiplusone.com/projects/qsignalmock/qsignalmock.h

This seems to be what I want - however as the author mentions this is missing a timeout/synchronization step.

As the linked post is quite old I'd like to know is there a better/more modern way to handle this? I can't believe I am the only person who would like to verify that a class emits its signals with expected data within a reasonable time frame.

For example lets say we have an object which starts a thread, sleeps and then emits a signal:

class ASyncObj : public QObject
{
public:
   void begin(); // fires OnResult after ~10 seconds using QTimer or QThread for example
signals:
   void OnResult(bool wasError);
};

TEST_F(ASyncTest, DidSignalFire)
{
    ASyncObj testObj;
    testObj.begin();

    // How can I wait for a timeout and verify that OnResult was called with a value of false?
}

Edit:

In the end I used QSignalSpy but noticed it has an issue it detecting signals being emitted depending on if it was sync or async. So I came up with this:

class QSignalSpyEx : public QSignalSpy
{
public:
    QSignalSpyEx(const QObject* obj, const char* aSignal)
        : QSignalSpy(obj, aSignal)
    {

    }

    bool waitForSignal(int timeout = 5000000)
    {
        // if true then signal was emitted synchronously  
        bool result = count() > 0;
        if (!result)
        {
            // if false then wait for async emit 
            result = wait(timeout);
        }
        return result;
    }
};

This makes my original example become:

TEST_F(ASyncTest, DidSignalFire)
{
    ASyncObj testObj;

    QSignalSpyEx spy(&testObj, SIGNAL(OnResult(bool)));

    testObj.begin();

    spy.waitForSignal(); // assert true
    spy.takeFirst().at(0).toBool(); // assert whatever you expected the result to be

}
¿Fue útil?

Solución

I don't know why you do not use QtTestLib (it is quite handy). Anyway this contains QSignalSpy which allows to test signals.
You should call wait(int) method which starts event loop until signal arrives or until timeout occurs.

I'm pretty sure you can mix it with googletest.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top