GoogleTest how to use InvokeArgument With WithArg
Asked Answered
R

3

7

I have a mock function:

MOCK_METHOD4(my_func, int(double, double, void* (*cb) (int), int p1));

I want to invoke 2nd (0-based) argument of above function with the 3rd argument as parameter, i.e., invoke "cb" function with "p1" as parameter. How can I do that?

I can invoke "cb" with some custom value using InvokeArgument:

ON_CALL(mockObj, my_func(_, _, _, _)).
                WillByDefault(DoAll(
                        IgnoreResult(InvokeArgument<2>(10)),
                        Return(0)));

But I want to invoke it with an actual parameter passed to the same mocked function call.

Reiterate answered 7/7, 2016 at 7:19 Comment(0)
S
5

You can define an ACTION to invoke your callback. Something like below:

ACTION(CallCb) {
  arg2(arg3);
}

...

ON_CALL(*mockObj, my_func(_, _, _, _))
  .WillByDefault(
     DoAll(CallCb(),
           Return(0)));
Spurrier answered 7/7, 2016 at 8:25 Comment(2)
Sounds great, but the details would help. How are symbols arg2 and arg3 bound?Macario
@Macario "arg2" and "arg3" are gmock keywords. See the Action docs. Note for anyone trying to use ACTION_Pk, the "k" is supposed to be the number of arguments, e.g. ACTION_P4Jointure
A
3

Since DoAll processes actions in sequence, you could save 3rd argument value to an external variable and then invoke 2nd argument with that variable as parameter.

int p;
ON_CALL(mockObj, my_func(_, _, _, _)).
            WillByDefault(DoAll(
                    SaveArg<3>(&p),
                    IgnoreResult(InvokeArgument<2>(p)),
                    Return(0)));
Apure answered 7/7, 2016 at 8:19 Comment(1)
It looks like all actions are instantiated at once, so the initial value of p has already been copied. This means that while the SaveArg works, InvokeArgument still uses the old value.Jointure
H
3

Unfortunately, combining WithArg and InvokeArgument does not work. However, you could use Invoke and match the callback function passed to the mocked method. Something like this:

EXPECT_CALL(*m_pInstallManagerMock, my_func(_, _, my_callback, _)).
            WillOnce(DoAll(
                    WithArg<3>(IgnoreResult(Invoke(my_callback))),
                    Return(0)));
Heuser answered 7/7, 2016 at 8:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.