我正在尝试结合使用QTest
和Catch
和QSignalSpy
来测试我的应用程序。我不得不说,我正在使用Qt 5.10.0,这可能很重要。
最近我偶然发现了一种奇怪的行为,我无法真正解释。
main.cpp
#include "testing/catch2.hpp"
#include <QtTest/qtest.h>
#include "TestCases.h"
TEST_CASE("MyTest") {
TestCases tc;
QTest::qExec(&tc);
}
TestCases.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);
}
};
TestObject.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错误?如果有意的话,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。