1

我正在尝试QTest结合使用CatchQSignalSpy测试我的应用程序。我不得不说,我使用的是 Qt 5.10.0,这可能很重要。

最近我偶然发现了一种奇怪的行为,我无法真正解释。

主文件

#include "testing/catch2.hpp"
#include <QtTest/qtest.h>
#include "TestCases.h"

TEST_CASE("MyTest") {
    TestCases tc;
    QTest::qExec(&tc);
}

测试用例.h

#pragma once
#include <QObject>
#include <QDebug>
#include <QSignalSpy>
#include "testing/catch2.hpp"
#include "TestObject.h"

class TestCases : public QObject {
    Q_OBJECT

    private slots:
    void firstTest() {
        nameSpace::TestObject o;
        QSignalSpy s(&o, &nameSpace::TestObject::valueChanged);
        o.setValue();
        REQUIRE(s.size() == 1);
        auto var = s.takeFirst();
        CHECK(var.size() == 0);
    }
    void secondTest() {
        nameSpace::TestObject o;
        QSignalSpy s(&o, &nameSpace::TestObject::objectChanged);
        o.changeObject();
        REQUIRE(s.size() == 1);
        auto var = s.takeFirst();
        CHECK(var.size() == 1);
    }
}; 

测试对象.h

#pragma once
#include <QObject>

namespace nameSpace
{

    struct MyObject
    {

    };

    class TestObject : public QObject {
        Q_OBJECT

    public:
        TestObject() {
        }
        void setValue() {
            emit valueChanged();
        }

        void changeObject()
        {
            MyObject obj;
            emit objectChanged(obj);
        }

    signals:
        void valueChanged();
        // Why I need to add a namespace here?
        void objectChanged(const nameSpace::MyObject&); 
    };
}

Q_DECLARE_METATYPE(nameSpace::MyObject);

如果我将运行发布的代码,我将获得以下输出,这对我来说很好。

********* Start testing of TestCases *********
Config: Using QtTest library 5.10.0, Qt 5.10.0 (i386-little_endian-ilp32 shared (dynamic) release build; by MSVC 2015)
PASS   : TestCases::initTestCase()
PASS   : TestCases::firstTest()
PASS   : TestCases::secondTest()
PASS   : TestCases::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 9ms
********* Finished testing of TestCases *********
===============================================================================

但是,如果我将行更改void objectChanged(const nameSpace::MyObject&);void objectChanged(const MyObject&);我获得以下错误输出:

********* Start testing of TestCases *********
Config: Using QtTest library 5.10.0, Qt 5.10.0 (i386-little_endian-ilp32 shared (dynamic) release build; by MSVC 2015)
PASS   : TestCases::initTestCase()
PASS   : TestCases::firstTest()
QWARN  : TestCases::secondTest() QSignalSpy: Unable to handle parameter '' of type 'MyObject' of method 'objectChanged', use qRegisterMetaType to register it.
PASS   : TestCases::secondTest()
PASS   : TestCases::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 7ms
********* Finished testing of TestCases *********
===============================================================================

所以有必要在信号定义中包含看似多余的命名空间。搜索并找到这个错误花了我半天时间,现在我也想了解这种行为的可能原因。这是故意的还是 Qt Bug?如果是故意的,那么 Qt 文档中的这个位置在哪里。

这有点类似于为什么必须写

Q_DECLARE_META_TYPE(nameSpace::MyObject)

代替

namespace nameSpace {
     Q_DECLARE_META_TYPE(MyObject)
}

请参阅文档:https ://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE 。

4

0 回答 0