Я пытаюсь использовать 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 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.