使用 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中,我们有:
Invoke(f)
, Invoke(object_pointer, &class::method)
, InvokeWithoutArgs(f)
, InvokeWithoutArgs(object_pointer, &class::method)
将转发(或不转发)提供给模拟函数的参数被称为。
InvokeArgument<N>(arg1, arg2, ..., argk)
好像是为了调用其中一个参数。
WithArg<N>(a)
和 WithArgs<N1, N2, ..., Nk>(a)
似乎是 select 原始函数的哪些参数被转发。
我想我遗漏了一些很明显的东西,但我有点卡在这里,所以任何建议都会有所帮助。
一个可能的选择是使用 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)
));
我有一个模拟方法。当它被调用时,我希望它在调用其正常行为之前调用另一个函数。像 :
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中,我们有:
Invoke(f)
,Invoke(object_pointer, &class::method)
,InvokeWithoutArgs(f)
,InvokeWithoutArgs(object_pointer, &class::method)
将转发(或不转发)提供给模拟函数的参数被称为。InvokeArgument<N>(arg1, arg2, ..., argk)
好像是为了调用其中一个参数。
WithArg<N>(a)
和WithArgs<N1, N2, ..., Nk>(a)
似乎是 select 原始函数的哪些参数被转发。
我想我遗漏了一些很明显的东西,但我有点卡在这里,所以任何建议都会有所帮助。
一个可能的选择是使用 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)
));