Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Qt信号进行Google测试/模拟_C++_Qt_Unit Testing_Googletest_Googlemock - Fatal编程技术网

C++ 使用Qt信号进行Google测试/模拟

C++ 使用Qt信号进行Google测试/模拟,c++,qt,unit-testing,googletest,googlemock,C++,Qt,Unit Testing,Googletest,Googlemock,我试图测试一个基于QObject的类,它将异步地发出信号(实际上是从后台线程发出信号) 我在这里看到一篇关于这样做的帖子: 链接到此源代码的: 这似乎是我想要的-然而,正如作者所提到的,这缺少了一个超时/同步步骤 由于链接的帖子很旧,我想知道有没有更好/更现代的方法来处理这个问题?我真不敢相信我是唯一一个想验证一个类是否在合理的时间范围内使用预期数据发出信号的人 例如,假设有一个对象启动线程,休眠,然后发出信号: class ASyncObj : public QObject { publ

我试图测试一个基于
QObject
的类,它将
异步地发出信号(实际上是从后台线程发出信号)

我在这里看到一篇关于这样做的帖子:

链接到此源代码的:

这似乎是我想要的-然而,正如作者所提到的,这缺少了一个超时/同步步骤

由于链接的帖子很旧,我想知道有没有更好/更现代的方法来处理这个问题?我真不敢相信我是唯一一个想验证一个类是否在合理的时间范围内使用预期数据发出信号的人

例如,假设有一个对象启动线程,休眠,然后发出信号:

class ASyncObj : public QObject
{
public:
   void begin(); // fires OnResult after ~10 seconds using QTimer or QThread for example
signals:
   void OnResult(bool wasError);
};

TEST_F(ASyncTest, DidSignalFire)
{
    ASyncObj testObj;
    testObj.begin();

    // How can I wait for a timeout and verify that OnResult was called with a value of false?
}
编辑:

最后,我使用了QSignalSpy,但注意到它有一个问题,即根据同步还是异步来检测发出的信号。所以我想到了这个:

class QSignalSpyEx : public QSignalSpy
{
public:
    QSignalSpyEx(const QObject* obj, const char* aSignal)
        : QSignalSpy(obj, aSignal)
    {

    }

    bool waitForSignal(int timeout = 5000000)
    {
        // if true then signal was emitted synchronously  
        bool result = count() > 0;
        if (!result)
        {
            // if false then wait for async emit 
            result = wait(timeout);
        }
        return result;
    }
};
这使我最初的例子变成:

TEST_F(ASyncTest, DidSignalFire)
{
    ASyncObj testObj;

    QSignalSpyEx spy(&testObj, SIGNAL(OnResult(bool)));

    testObj.begin();

    spy.waitForSignal(); // assert true
    spy.takeFirst().at(0).toBool(); // assert whatever you expected the result to be

}

我不知道你为什么不用(它很方便)。无论如何,它包含允许测试信号的组件。
您应该调用启动事件循环直到信号到达或超时发生的方法


我很确定你可以把它和谷歌测试混在一起。

看起来这样不行,因为wait(int)有一个竞争条件。如果在调用wait之前发出信号,那么看起来好像从未发出过信号,有没有办法解决这个问题?不会有竞争条件!1.您应该在开始实际测试之前(调用begin之前)创建
QSignalSpy
,然后在调用
begin
之后调用
wait
,2。默认情况下,由不同线程发出的信号调用的插槽由目标线程的事件循环处理。我会这样做,并且存在争用条件,因为这取决于信号是异步还是同步发出的。如果同步,那么signal spy wait将认为没有发出任何信号,否则会发出信号。不过我还是设法创建了一个包装器来解决这个问题。如果Qt在这种情况下有一个QSignalSpy::wait(millis,emitCount),那就太好了(如果count已经是emitCount,则返回时不等待)