Search code examples
c++unit-testinggoogletestgooglemock

google mock - EXPECT_CALL triggers even though function has different argument


I have EXPECT_CALL(MockObj, func("abc")).Times(1) and MockObj is a NiceMock

In my function under test, there is a call MockObj.func("def") in addition to MockObj.func("abc").

I would expect that the reasonable thing to do is for Google Mock to say

oh look we call func("def") but the arguments do not match the EXPECT_CALL; nothing to see here

But instead it "complains":

unknown file: Failure

Unexpected mock function call - taking default action specified at:

C:/work/unit_test.cpp:36:

Function call: func(84bf3d9 pointing to "def")

      Returns: 1

Google Mock tried the following 1 expectation, but it didn't match:

unit_test.cpp:50: EXPECT_CALL(MockObj, func("abc"))...

Expected arg #0: is equal to 84c8b96 pointing to "abc"

Actual: 84bf479 pointing to "def"

Expected: to be called once

Actual: called once - saturated and active

First notice that the expectation was still satisfied because MockObj.func("abc") was called

I understand why GMock threw the error: I declared an expection on func so it tried to match the call to func to the expectation but it didn't match the arguments so error

Fine.

But why does GMock throw an error? Since the arguments don't match, why was this behavior selected i.e.

throw an error if the function matches existing EXPECT_CALL but not the arguments


Solution

  • The direct answer to your question "But why does GMock throw an error? " is: because it is designed that way.

    AFAIU googlemock - the googlemock in your case works this way:

    1. EXPECT_CALL(MockObj, func("abc")); - means: "I am interested in Obj::func in my tests"
    2. MockObj being NiceMock means: "I do not care about any other functions of Obj that are not explicit subject of EXPECT_CALL"

    So - if your code-under-test calls func("def") - then google-mock does that:

    1. we are interested in func - so let's check
    2. we do not expect "def" - so fail the test

    Probably you know that you should do this:

    EXPECT_CALL(MockObj, func(StrNe("abc"))).Times(AnyNumber()); // meaning - do not care EXPECT_CALL(MockObj, func("abc")); // TImes(1) is default - you might skip it