c++ - QObject::deleteLater 在我的 Qt 测试中没有按预期调用

标签 c++ qt qtestlib

我正在测试一个共享库,其中包含内部对 deleteLater 的调用。 库中没有运行事件循环,因此应用程序需要运行事件循环,以便正确释放所有内存。

但是在测试中,对象dtor并没有像预期的那样被调用。

例如:

void test1() 
{
    Foo foo;
    QSignalSpy spy(&foo, SIGNAL(mySignal(Status)));

    foo.do(); // should trigger mySignal 

    QVERIFY(spy.wait(10000)); // event loop started for 10 s max
    QCOMPARE(spy.count(), 1);
    QList<QVariant> sig = spy.takeFirst();
    Foo::Status status = qvariant_cast<Foo::Status>(sig.at(0));

    QVERIFY2(status == Foo:Ok, "Failed");
}

Foo 类看起来像这样:

class Foo : public QObject
{
Q_OBJECT

// ... methods, signals, slots..

private slots:
 // this call is asynchronous (depends on a network reply)
 void myslot() {
     //..
     m_obj->deleteLater();
     emit mySignal(Foo:Ok);
  }
};

我在 m_obj 的 dtor 中添加了一些调试打印,并且在执行 test1 时不会调用它。

但是,如果我执行两次测试(通过添加一个 test2 插槽,它是 test1 的拷贝),那么它会被调用一次。

我的理解是,当发出信号时,它会停止 spy 事件循环,然后永远不会调用 deleteLater。 之后,第二个事件循环在 test2 中开始,它处理来自前一个 test1 的未决删除。

是否正确? 谢谢。

最佳答案

是的,你是对的。由于 QSignalSpyFoo 存在于同一个线程中,因此信号 mySignal 不是通过事件循环传递的,而是通过直接连接传递的。因此,事件循环在 myslot 中发出信号后立即停止。然而,由于 myslot 被同一个事件循环调用,控制权仅在 myslot 返回时返回给它。因此,当事件循环可能执行 deleteLater 请求的清理时,它已经停止了。

如果你想测试 m_obj 是否被正确清理,你可以创建一个额外的 QSignalSpy 并将其连接到 QObject::destroyed 表示每个 QObject 在被销毁时都会发出信号。

但是,您需要将 m_obj 作为 Foo 的依赖项传递到构造函数中或通过 setter 而不是在 Foo< 中构造它 本身。

然后测试看起来像这样:

void test1()
{
    auto obj = new Obj{}; // will be assigned to `Foo::m_obj`
    Foo foo{obj};

    QSignalSpy deletion_spy(obj, &QObject::destroyed);
    QSignalSpy mysignal_spy(&Foo, &Foo::mySignal);

    QVERIFY(deletion_spy.wait(10000));
    QCOMPARE(deletion_spy.count(), 1); // verify that `obj` got deleted

    QCOMPARE(mysignal_spy.count(), 1);
    QList<QVariant> sig = spy.takeFirst();
    Foo::Status status = qvariant_cast<Foo::Status>(sig.at(0));

    QVERIFY2(status == Foo:Ok, "Failed");
}

关于c++ - QObject::deleteLater 在我的 Qt 测试中没有按预期调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52405841/

相关文章:

c++ - C++中许多for循环的紧凑形式

qt - 平面 QTreeView 项目 - 不嵌套

c++ - QTestLib 是否可以在运行时显示它正在测试的 GUI?

java - C++可以调用Java代码吗?

C++ 变量在 While 循环中不更新

c++ - 矩阵类 Directx 和 OpenGL

c++ - 如何让 macdeployqt 在复制 QtWebEngineCore 框架时更改 QtWebEngineProcess.app 中的库名称

c++ - 将 Qt 与 DirectX 一起使用?

c++ - 如何使用 qteSTLib 测试完整的 Qt5 GUI?