Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sleep() call inside gmock's EXPECT_CALL

I'm trying to do some sleep inside .WillOnce before invoking FuncHelper. So I need something similar to the following:

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

Is it possible to call sleep() with an arg inside .DoAll? C++98 is preferrable.

UPD:

The solution is based on @Smeeheey answer and uses 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)));
like image 223
Rom098 Avatar asked Jun 07 '16 12:06

Rom098


People also ask

What is expect call in Gmock?

In gMock we use the EXPECT_CALL() macro to set an expectation on a mock method. The general syntax is: EXPECT_CALL(mock_object, method(matchers)) . Times(cardinality) .

How do you mock a function in Gmock?

Mocking Free Functions It is not possible to directly mock a free function (i.e. a C-style function or a static method). If you need to, you can rewrite your code to use an interface (abstract class).

What is Expect_call?

EXPECT_CALL not only defines the behavior, but also sets an expectation that the method must be called with the given arguments, for the given number of times (and in the given order when you specify the order too).

What is Googlemock?

Gmock is a mocking framework for the Groovy language. Gmock is all about simple syntax and readability of your tests so you spend less time learning the framework and more writing code. To use Gmock just drop the gmock jar file in your classpath.


2 Answers

Since you said C++98 is preferable rather than compulsory, first I'll give a nice neat C++11 answer:

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

Otherwise (for C++98), define a wrapper function elsewhere in the code:

void sleepForTime()
{
    sleep(TimeToSleep);
}

And then:

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

Note that here, TimeToSleep will have to be a global variable.

EDIT: As per suggestion from OP in comments, if TimeToSleep is a compile-time constant you can avoid the global variable:

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

...

EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs(sleepForTime<TimeToSleep>), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));
like image 71
Smeeheey Avatar answered Sep 20 '22 01:09

Smeeheey


If you prefer C++98 solution, I would suggest using std::bind1st:

EXPECT_CALL(*_mock, Func(_,_,_)).Times(1)
  .WillOnce(DoAll(InvokeWithoutArgs(std::bind1st(sleep, TimeToSleep)), 
                  Invoke(_mock, &M_MyMock::FuncHelper)));
like image 31
Marko Popovic Avatar answered Sep 20 '22 01:09

Marko Popovic