使用gmock将值设置为void **参数的通用自定义操作

时间:2015-12-03 14:44:50

标签: c++ googletest googlemock gmock

我一直在试用一些使用gmock使用COM接口的代码。 Win32功能 通过void **参数使用COM返回接口指针。嘲笑时 例如,调用QueryInterface函数将返回指向IPersistFile的指针 界面,我做以下

CPersistFileMock mockIPersistFile;
EXPECT_CALL(mockIShellLink, QueryInterface(_, _)).WillOnce(DoAll(
    SetArg1ToIPersistFile(&mockIPersistFile), Return(S_OK)));

其中SetArg1ToIPersistFile是一个定义如下的自定义操作:

ACTION_P(SetArg1ToIPersistFile, pIPersistFile) {
    *reinterpret_cast<CPersistFileMock**>(arg1) = pIPersistFile;
}

这很有效,但问题是您必须为每个组合编写一个新的自定义操作 参数索引和需要通过void **参数返回的类型。有办法吗? 概括此自定义操作,以便可以应用它而不管类型和参数索引(to 像SetArgPointee<>这样的东西,但也知道类型)。

1 个答案:

答案 0 :(得分:3)

这个问题一直困扰着我们的团队,我们知道我们可以通过使用args来利用std::get<>是一个元组的事实,但我们不知道如何传递参数索引和类型以通用的方式。最后,我的一位同事想出了如何制作行动模板。这是最终的实施:

ACTION_TEMPLATE(SetArgVoidPtrPtr, HAS_2_TEMPLATE_PARAMS(typename, Type, unsigned, uIndex), AND_1_VALUE_PARAMS(value))
{
    *reinterpret_cast<Type**>(std::get<uIndex>(args)) = value;
}

以及它如何在上述IFilePersist示例的上下文中使用:

EXPECT_CALL(mockIShellLink, QueryInterface(_, _)).WillOnce(DoAll(
    SetArgVoidPtrPtr<CPersistFileMock, 1>(&mockIPersistFile), Return(S_OK)));

请注意,此方法可以在一般情况下使用,其函数通过void **参数返回值。只是想把它放在那里,因为我没有找到关于此的更多信息。希望这可以帮助有类似问题的人。