gmock EXPECT_CALL 中的 sleep() 调用

sleep() call inside gmock's EXPECT_CALL

我正在尝试在调用 FuncHelper 之前在 .WillOnce 中做一些睡眠。所以我需要类似于以下内容的内容:

EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs(sleep(TimeToSleep)), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));

是否可以在 .DoAll 中使用 arg 调用 sleep()? C++98 是首选。

更新:

该解决方案基于@Smeeheey 答案并使用 C++98。

template <int N> void Sleep ()
{
  sleep(N);
}
...
EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs(Sleep<TimeToSleep>), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));

既然你说 C++98 是 可取的 而不是强制性的,首先我会给出一个很好的 C++11 答案:

EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs([TimeToSleep](){sleep(TimeToSleep);}), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));

否则(对于 C++98),在代码的其他地方定义一个包装函数:

void sleepForTime()
{
    sleep(TimeToSleep);
}

然后:

EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs(sleepForTime), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));

注意这里的TimeToSleep必须是一个全局变量。

编辑: 根据 OP 在评论中的建议,如果 TimeToSleep 是编译时常量,则可以避免使用全局变量:

template <int Duration>
void sleepForTime()
{
    sleep(Duration);
}

...

EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs(sleepForTime<TimeToSleep>), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));

如果您更喜欢 C++98 解决方案,我建议使用 std::bind1st:

EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs(std::bind1st(sleep, TimeToSleep)), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));

定义 gmock action

ACTION_P(Wait, seconds)
{
  ::sleep(seconds)
}

然后以简洁明了的方式使用它:

EXPECT_CALL(...).WillOnce(Wait(3));

我认为这是在 gmock 测试中等待的最“gmockish”和最干净的方式,特别是如果需要在测试的多个地方等待。