Search code examples
c++googletest

Where expectations are stored in Google Test?


I cannot find it neither in the CookBook nor Advanced Part of Google Test Framework Tutorial. I have for example the following function that creates expectations:

void testFunc()
{
    for (std::size_t i = 0; i < 10; i++)
        EXPECT_CALL(dummyMock, mockFunc).WillOnce(Return(i))    
}

And then I invoke this function in some Test Case

TEST(UnitTestCase, TestSomeMockFunc)
{
    TestSomeFunction();
    testFunc();
}

The question is how Google Test execute the code from testFunc. Does it make it after TestSomeFunction's execution? Or before it, for example during compilation time? And finally, where each "EXPECT_CALL" statement from testFunc is stored after execution of this function?


Solution

  • I'll try to answer your questions one by one, and then will proceed to the problems with your snippets.

    The question is how Google Test execute the code from testFunc.
    It doesn't. This part works just like any C++ code. First TestSomeFunction() is called, then follows testFunc(), which runs loop 10 times. Nothing unusual here.

    Does it make it after TestSomeFunction's execution?
    Yes, because testFunc() is called after TestSomeFunction(). Functions are called sequentially, GoogleMock in theory could apply some macro magic, but this is not the case.

    Or before it, for example during compilation time?
    EXPECT_CALL macro is expanded during preprocessing phase, before compilation. Whatever is under it, is executed during runtime, just like any other function.

    And finally, where each "EXPECT_CALL" statement from testFunc is stored after execution of this function?
    I don't know that, but most likely it is stored somehow in mock object (i.e. dummyMock). I believe it's there because all expectations are verified in mock's destructor.


    Now, about the first snippet, this is one feature of GoogleMock that I find more annoying than useful on most occasions.

    for (std::size_t i = 0; i < 10; i++)
        EXPECT_CALL(dummyMock, mockFunc()).WillOnce(Return(i))
    

    Above code create 10 call expectations, but newer call expectations shadow previous ones. So, if your code will proceed to call mockFunc 10 times, you will have 9 expectations that were not called and 1 expectation called 10 times (also failing, it wanted single call).

    If you don't need each call to return different values, use simply

    EXPECT_CALL(dummyMock, mockFunc()).Times(10).WillRepeatedly(Return(0));
    

    Hovewer, if you need different values each time, there are few things to consider:

    1. Use RetiresOnSaturation() - Add it as the last call in the chain (after WillRepeatedly()). This will let you avoid the problem of shadowing previous expectations, because each expectation will be ignored after it's fulfilled.
    2. Reverse order of adding expectations. - GoogleMock adds new expection in a Last In, First Out (LIFO) manner. This means the latest created expectation will be the first matched against (and executed).

    Thus, to create GoogleMock expectations in such a way that it will return next number with each function call, the following code should work:

    void testFunc()
    {
        for (std::size_t i = 9; i >= 0; i++)
            EXPECT_CALL(dummyMock, mockFunc()).WillOnce(Return(i)).RetiresOnSaturation();    
    }
    

    Of course, expectations should be set before mock functions are called in tested code, because otherwise GoogleMock will have no knowledge that you plan to do such things.