Search code examples
c++unit-testinggoogletestgooglemock

How do you mock a function that is part of that class under test gmock?


I am using googletest / googlemock (GTest/GMock). I am only able to test the code below when Selection naturally returns false. How would I simulate the example problem below?

I am having difficulty changing the return value of selection because it uses real code.

class frame
{
    bool Selection();
    void Actions();
};

void frame::Action()
{
    if (Selection())
    {
        // do something
    }
    else
    {
        // do something else
    }
}

void WrapAction()
{
    Frame->Action();
}

TEST_F(UITest, ActionWithSelectionTrue)
{
    EXPECT_CALL(*Frame, Selection()).WillOnce(Return(true));

    WrapAction();
}

TEST_F(UITest, ActionWithSelectionFalse)
{
    EXPECT_CALL(*Frame, Selection()).WillOnce(Return(false));
    WrapAction();
}

Solution

  • Traditional unit tests have the A3 form:

    1. Assemble (also called "Arrange"; setup your object under test)
    2. Act (perform the desired action on the object)
    3. Assert (validate the the proper values changed, events were emitted, etc.)

    This is a valid form for tests and does not require a mock framework at all.

    In a test with mocks, you may (depending on how your mock library works) have to amend this procedure to be A4:

    1. Assemble (including injecting mocked dependencies)
    2. Anticipate (set expectations on mocked dependencies by identifying expected calls, set return values, side effects, etc.)
    3. Act
    4. Assert (may have nothing else to assert if the mock expectations cover everything).

    In your case, it is not clear what you are mocking. Where are the dependencies you are injecting that you are replacing with mocks?

    Given the code you've shown us, I think you should use the A3 test pattern. That would mean in the "Assemble" section, you configure the object by setting the selection, then you perform your action on it and check the result.

    If you cannot work in the A3 pattern, this probably means you need to refactor to better separate your dependencies. When you do that, you can then mock and test with the A4 pattern.