首页 > 解决方案 > 如何从使用 GMock 模拟的模拟类中触发 Qt Signal

问题描述

我有一个类,它的接口正在执行一些上传,它是异步完成的,当上传完成时,它会触发一个信号来通知这个类的消费者工作已经完成。我正在尝试为注入模拟的消费者类编写一个测试,基本思想是当调用上传方法时,模拟应该触发其自身的完成信号。问题是被测试的消费者没有收到信号。我要么遗漏了一些东西,要么这不起作用。为简单起见,这里有一些虚假的实现:

上传者界面:

#include <QObject>

class IUploader : public QObject 
{
Q_OBJECT
public:
    IUploader() = default;
    ~IUploader() override = default;
    virtual void upload(int i) = 0;

signals:
    void finished(int i);
};

模拟:

#include <gmock/gmock.h>

#include "IUploader.h"

class UploaderMock : public IUploader
{
public:
   MOCK_METHOD(void, upload, (int i), (override));
};

考试:

#include <gtest/gtest.h>

#include "Consumer.h"
#include "UploaderMock.h"

TEST(Consumer, UploaderFinished_Should_TriggerCallback)
{
   // arrange
   UploaderMock uploader;

   ON_CALL(uploader, upload(11)).WillByDefault([&uploader](int i) {
      uploader.finished(i * 2);
   });
   
   Consumer consumer(&uploader);

   // act
   consumer.doUpload(11);
   
   // assert
   EXPECT_EQ(consumer.uploadResult(), 22);
}

消费者.h #include

#include "IUploader.h"

class Consumer : public QObject
{
Q_OBJECT
public:
    explicit Consumer(IUploader *uploader);
    ~Consumer() override = default;
    void doUpload(int i);
    int uploadResult() const;

private:
    IUploader *mUploader = nullptr;
    int mResult = -1;

private slots:
    void setResult(int i);
};

消费者.cpp

#include "Consumer.h"

Consumer::Consumer(IUploader *uploader) :
    mUploader(uploader)
{
    connect(uploader, &IUploader::finished, this, &Consumer::setResult);
}

void Consumer::doUpload(int i)
{
    mUploader->upload(i);
}

int Consumer::uploadResult() const
{
    return mResult;
}

void Consumer::setResult(int i)
{
    mResult = i;
}

发生的情况是我确实看到在 ON_CALL 中触发了操作,但我没有看到 Consumer 对象接收到任何信号。

Qt 和 GMock 可以实现这样的测试用例吗?测试方法完成后处理信号是否是时序问题?

标签: c++qtunit-testinggoogletestgmock

解决方案


推荐阅读