问题
It's a confusing situation i'm in. While testing state transitions for a QStateMachine, the following code fails to spy on the signal that causes the transition.
// Test transition to SS_STARTING
QSignalSpy spy(test_obj_, SIGNAL(StateChanged(int)));
// emmit StateChanged signal
test_obj_->SetState(SS_STARTING);
// Current state property should be SS_STARTING
QVERIFY(spy.wait()); //<--- fails test
QVERIFY(test_obj_->GetCurrentState() == SS_STARTING);
QCOMPARE(spy.count(), 1);
The following code passes the test!
// Test transition to SS_STARTING
QSignalSpy spy(test_obj_, SIGNAL(StateChanged(int)));
// emmit StateChanged signal
test_obj_->SetState(SS_STARTING);
// Current state property should be SS_STARTING
QTest::qWait(20); //<--- passes test
QVERIFY(test_obj_->GetCurrentState() == SS_STARTING);
QCOMPARE(spy.count(), 1);
I can also verify externally that the signal is being emitted using dbus-monitor.
I can go ahead and use QTest::qWait, it's no big deal, but i'm just confused as to why spy.wait isn't working.
Cheers, Simon
回答1:
Your test is incorrect, as soon as you set setState()
the signal is emitted, so spy.wait()
will no longer receive it. So the idea is to emit the signal a moment after spy.wait()
starts using a QTimer:
// Test transition to SS_STARTING
QSignalSpy spy(test_obj_, SIGNAL(StateChanged(int)));
// emmit StateChanged signal
// test_obj_->SetState(SS_STARTING);
QTimer::singleShot(0, [test_obj_](){ test_obj_->setState(SS_STARTING);}); // <----
QVERIFY(spy.wait());
QVERIFY(test_obj_->GetCurrentState() == SS_STARTING);
QCOMPARE(spy.count(), 1);
In its second example, the QTest::qWait()
is not necessary because the status changed synchronously
来源:https://stackoverflow.com/questions/55095175/qsignalspywait-fails-when-qtestqwait-succeeds