我在单元测试期间遇到一些情况,我希望某些QTimer的超时在某些QObject中触发一些插槽。如何做到这一点以及这次测试的一些常见陷阱并不是很明显。
答案 0 :(得分:9)
这种模式是我发现的作品。我怀疑它可能在某种程度上依赖于线程模型,因此我提供了一个YMMV的小注释。
假设你有一些
class Foo : public QObject{
...
public:
QTimer* _timer;
public slots:
virtual void onTimeout();
...
}
为简单起见,让我们假设这是一个私有实现类,这就是暴露定时器的原因,并且插槽是虚拟的,所以我们可以模拟它。
class MockFoo : public Foo{
public:
MOCK_METHOD0(onTimeout, void());
}
首先,当使用Qt中的QTimers和其他线程模型时,我们必须修改google test的'main'功能:
int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
QTimer exitTimer;
QObject::connect(&exitTimer, &QTimer::timeout, &app, QCoreApplication::quit);
exitTimer.start();
app.exec();
return ret;
}
接下来,在测试套件中:
TEST_F(Foo_Tests, onTimeout){
MockFoo* foo{new MockFoo};
//using Qt 5 convention, but do what you gotta do for signal spy in your setup
QSignalSpy timeoutSpy(foo->_timer, &QTimer::timeout);
QSignalSpy deleteSpy(foo, &QObject::destroyed);
foo->_timer->setInterval(0);
foo->_timer->setSingleShot(true);
EXPECT_CALL(*foo, onTimeout());
foo->_timer->start();
EXPECT_TRUE(timeoutSpy.wait(100));
foo->deleteLater();
deleteSpy.wait(100);
}
关于此的一些注意事项非常重要: