Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I repeatedly expect a sequence of calls?

I'm writing a test to verify the sequence of calls on an image processing thread. The relevant piece of test code looks like this:

Sequence s1, s2;
...
EXPECT_CALL(*mMockVideoSource, getFrame()).InSequence(s2).WillRepeatedly(Return(mFakeBuffer));
EXPECT_CALL(*mMockProcessor, processFrame(_,_)).InSequence(s2).WillRepeatedly(Return(0));
EXPECT_CALL(*mMockVideoSource, releaseFrame(_)).Times(AnyNumber()).InSequence(s2);
...

In this case, the sequence of calls is extremely important. getFrame(), processFrame() and releaseFrame() must be called in this order. Unfortunately, the above code isn't really accomplishing what I want. The above code will allow getFrame() to be called repeatedly before the call to processFrame(), and a call to getFrame() after releaseFrame() is considered an error since it breaks the sequence.

Is there a way to expect a specific sequence of calls to be made repeatedly? I don't care how many times the sequence is executed, so long as the functions are called in order: get, process, release, get, process, release...

like image 323
bstar55 Avatar asked May 27 '14 17:05

bstar55


1 Answers

You can create side action on calling your mock (https://code.google.com/p/googlemock/wiki/CookBook#Combining_Actions) and some global state like "lastAction".

Side action will look like:

void checkSequenceCorrectness(ActionType currAction)
{
    if (currAction == PROCESS_FRAME) EXPECT_EQ(GET_FRAME, lastAction);
    (more ifs)
    ...

    lastAction = currAction;
}

You can bind it to mock by:

EXPECT_CALL(*mMockProcessor, processFrame(_,_))
    .WillRepeatedly(DoAll
        Return(0), 
        Invoke(checkSequenceCorrectness(PROCESS_FRAME)));
like image 105
Maciej Oziębły Avatar answered Oct 07 '22 20:10

Maciej Oziębły