sha*_*era 5 c++ qt googletest qtimer
我在单元测试期间遇到一些情况,我希望某些QTimer的超时在某个QObject中触发一些插槽.如何做到这一点以及此测试的一些常见缺陷并不是很明显.
sha*_*era 11
这种模式是我发现的作品.我怀疑它可能在某种程度上依赖于线程模型,因此我提供了一个YMMV的小注释.
假设你有一些
class Foo : public QObject{
...
public:
QTimer* _timer;
public slots:
virtual void onTimeout();
...
}
Run Code Online (Sandbox Code Playgroud)
为简单起见,让我们假装这是一个私有实现类,这就是暴露计时器的原因,而插槽是虚拟的,所以我们可以模拟它.
class MockFoo : public Foo{
public:
MOCK_METHOD0(onTimeout, void());
}
Run Code Online (Sandbox Code Playgroud)
首先,当使用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;
}
Run Code Online (Sandbox Code Playgroud)
接下来,在测试套件中:
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);
}
Run Code Online (Sandbox Code Playgroud)
关于这一点的一些注意事项非常重要: