使用 Google C++ Mocking Framework (Google Mock) (V1.5) 将任意参数传递给调用的方法

Passing arbitrary arguments to invocked methods with Google C++ Mocking Framework (Google Mock) (V1.5)

我有一个模拟方法。当它被调用时,我希望它在调用其正常行为之前调用另一个函数。像 :

EXPECT_CALL(*my_obj, MockedMethod(_,_,_,_,_,_))
    .WillOnce(DoAll(
        Invoke(my_obj, &SomeAdditionalMethodIWantToCall),
        Invoke(my_obj, &DefaultBehavior),
        ));

唯一的问题是 SomeAdditionalMethodIWantToCall 需要的参数与提供给 MockedMethod 的参数完全无关。我希望能够给他们,但我在语法上苦苦挣扎。我希望有类似的东西(用假语法):

EXPECT_CALL(*my_obj, MockedMethod(_,_,_,_,_,_))
    .WillOnce(DoAll(
        Invoke(my_obj, &SomeAdditionalMethodIWantToCall, arg1, arg2, arg3),
        Invoke(my_obj, &DefaultBehavior),
        ));

我在文档中寻找过这样的东西,但没有成功。

Using a Function or a Functor as an Action中,我们有:

Composite Actions

我想我遗漏了一些很明显的东西,但我有点卡在这里,所以任何建议都会有所帮助。

一个可能的选择是使用 Assign 操作将参数值保存到 class 变量,然后使用助手调用另一个函数。使用以下期望:

EXPECT_CALL(*my_obj, MockedMethod(_,_,_,_,_,_))
    .WillOnce(DoAll(
        Assign(&classVariable1, arg1),
        Assign(&classVariable2, arg2),
        Assign(&classVariable3, arg3),
        InvokeWithoutArgs(my_obj, &MyClass::SomeAdditionalMethodIWantToCallHelper),
        Invoke(my_obj, &MyClass::DefaultBehavior),
        ));

然后定义你的辅助函数如下:

void MyClass::SomeAdditionalMethodIWantToCallHelper()
{
    SomeAdditionalMethodIWantToCall(classVariable1, classVariable2, classVariable3);
}

编辑

另一种可能的选择是编写一个自定义操作,该操作接受一个指向成员函数的指针以及您希望传递给它的参数。这更接近您最初想要的语法。这是自定义操作:

ACTION_P5(InvokeUnrelatedFunction, classPointer, pointerToMemberFunc,
          first, second, third)
{
    (classPointer->*pointerToMemberFunc)(first, second, third);
}

以下是您在预期中使用它的方式:

EXPECT_CALL(*my_obj, MockedMethod(_,_,_,_,_,_))
    .WillOnce(DoAll(
        InvokeUnrelatedFunction(my_obj, &MyClass::SomeAdditionalMethodIWantToCall,
                                arg1, arg2, arg3),
        Invoke(my_obj, &MyClass::DefaultBehavior),
        ));

如果您使用的是 c++11,则可以像这样使用 lambda 函数:

EXPECT_CALL(*my_obj, MockedMethod(_,_,_,_,_,_))
.WillOnce(DoAll(
    InvokeWithoutArgs([&]() { 
        my_obj->SomeAdditionalMethodIWantToCall(arg1, arg2, arg3); 
    },
    Invoke(my_obj, &DefaultBehavior)   
));