Сравнение подходов
| Характеристика | QSignalSpy | Моки (например, Google Mock) |
|---|
| Цель | Отслеживание вызова сигналов | Проверка вызова методов, поведения объектов |
| Сфера применения | Qt-ориентированные проекты (QObject) | Общий C++ (без привязки к Qt) |
| Проверка сигналов | Да (встроено) | Нет напрямую, но можно проверить вызов слотов |
| Тип контроля | Пассивное наблюдение за сигналом | Активная проверка вызова метода, через ожидания |
| Работает с сигналами/слотами | Да (QObject::connect) | Только методы, нет сигналов (без обёртки) |
| Асинхронная поддержка | Да (spy.wait(timeout)) | Требует внешней синхронизации |
| Проверка аргументов | Да (spy.at(i).at(j)) через QVariant | Да (точное сравнение типов и значений аргументов) |
| Интеграция с Qt | Полная (QtTest, QObject) | Ограниченная (обычно сторонние библиотеки) |
| Инструмент Mocking | Не поддерживает | Поддерживает (EXPECT_CALL, ON_CALL, т.д.) |
| Потоки | Только в основном потоке | Можно использовать и в других потоках |
| Лёгкость использования | Очень прост в Qt | Требует подготовки мок-классов |
Пример: QSignalSpy
class Worker : public QObject {
Q_OBJECT
signals:
void done(int result);
};
void testSignalWithSpy() {
Worker w;
QSignalSpy spy(&w, SIGNAL(done(int)));
emit w.done(123);
QCOMPARE(spy.count(), 1);
QList<QVariant> args = spy.takeFirst();
QCOMPARE(args.at(0).toInt(), 123);
}
Пример: Мок через Google Mock
class Receiver {
public:
virtual void onDone(int result) = 0;
virtual ~Receiver() = default;
};
class MockReceiver : public Receiver {
public:
MOCK_METHOD(void, onDone, (int), (override));
};
void testWithMock() {
MockReceiver mock;
EXPECT_CALL(mock, onDone(123)).Times(1);
Worker w;
QObject::connect(&w, &Worker::done, [&mock](int r) {
mock.onDone(r);
});
emit w.done(123);
}
Что выбрать?
| Сценарий | Использовать |
|---|
| Проверить факт вызова сигнала | QSignalSpy |
| Проверить аргументы сигнала | QSignalSpy |
| Проверить поведение сложного компонента, реагирующего на сигнал | Mock |
| Нужно протестировать последовательность вызовов, состояния | Mock |
| Вы не используете Qt | Mock |
| Вы используете Qt GUI/slots | QSignalSpy |
Итого
QSignalSpy | Моки (Google Mock и др.) |
|---|
| ✅ Легко применим в Qt | ✅ Гибкие ожидания, поведение |
| ✅ Не требует дополнительных классов | ⛔ Требует интерфейсов, описания классов |
| ⛔ Работает только с сигналами | ✅ Можно подменить любую часть системы |
| ✅ Хорошо работает с асинхронным кодом | ⛔ Требуется внешняя синхронизация |
Комбинированный подход
Ты можешь использовать оба подхода:
QSignalSpy — чтобы проверить, что сигнал был отправлен.
- Моки — чтобы проверить, что получатель отреагировал должным образом.