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
}