如何在 QtTest 上执行 QtConcurrent::run 调用

问题描述 投票:0回答:1

我正在为我的应用程序构建测试。目前,代码将所有数据库调用委托给单独的工作线程。当尝试测试函数时,我发现没有调用线程执行。

我看到我可以调用

QCoreApplication::exec()
来执行事件循环调用,但这会执行一些然后永远挂起。

Hereanda_skoa建议“使用在结果信号上退出的测试本地 QEventLoop 实例”,但我不知道该怎么做。

以下是当前代码的示例:

class TestUserService : public QObject
{
    Q_OBJECT

    const QString dbPath = "test_DB.db";

private slots:
    void initTestCase()
    {
        DbManager* db = new DbManager();
        QFuture<void> connection = db->connect(dbPath);

        connection
            .then([](){
                qInfo() << "Database Connected!";
            }).onFailed([](Exception e){
                qDebug() << "Error initializing database" << e.what();
            }); // None of this ever runs.
    }
}
QFuture<void> DbManager::connect(const QString &path)
{
    return QtConcurrent::run(DbThread::instance()->pool(), [path]() {
        QSqlDatabase m_db = QSqlDatabase::addDatabase("QSQLITE", "main");
        m_db.setDatabaseName(path);

        if (!m_db.open())
        {
            throw Exception("Error connecting to the database");
        }
    });
}

此测试中的许多后续测试也是包装在返回 QFuture 的并发运行上的方法。但是,我可以看到没有任何 lambda 被执行,因为我可以看到没有生成调试日志,并且所有测试都失败了,因为值没有更改,因为它们的逻辑没有执行。

如果我在

QCoreApplication::exec()
末尾添加
initTestCase()
,则 lambda 会被执行,但它会永远挂在那里,并且不再执行任何其他操作。

我的应用程序一切正常,所以我确信缺少某些内容仅用于测试。

该怎么办?

multithreading qt events qt6
1个回答
0
投票

因为你的问题不包含最小的可重现示例,所以我什至不想回答它,但我会尝试回答你的问题的标题,包括你对 Qt 中心的链接讨论的疑问:

“使用在结果信号上退出的测试本地 QEventLoop 实例”,但我不知道如何做到这一点

您可以熟悉QFutureWatcher,它允许使用信号和槽监视

QFuture
。我在下面显示了一个在 Qt 测试应用程序中使用本地事件循环的代码片段。它可能无法直接适用于您的问题,但希望能为您提供前进的想法。

QFutureWatcher<int> watcher;
QEventLoop loop;
QSignalSpy spy(&watcher, &QFutureWatcher<int>::finished);
QObject::connect(&watcher, &QFutureWatcherBase::finished, 
                 &loop, &QEventLoop::quit, Qt::QueuedConnection);
auto future = QtConcurrent::run([](){
    return 10;
});
watcher.setFuture(future);
QCOMPARE(spy.count(), 0);

loop.exec();

QCOMPARE(watcher.result(), 10);
QCOMPARE(spy.count(), 1);
© www.soinside.com 2019 - 2024. All rights reserved.