C++ 使用Google Mocks模拟自由函数
我有以下自由函数sig:C++ 使用Google Mocks模拟自由函数,c++,unit-testing,googlemock,C++,Unit Testing,Googlemock,我有以下自由函数sig: ReturnT getFirstAttributeHandle(ParentHandleT a, AttributeHandleT* b); 我需要将这样一个函数的地址传递给迭代器的构造函数,迭代器在这些句柄上进行迭代。由于此函数的具体实现访问外部依赖项,因此我需要模拟它 我想用GoogleMock来模拟这个函数,但我不知道怎么做 这就是我所尝试的: class IAttributeIterator { public: virtual ReturnT getF
ReturnT getFirstAttributeHandle(ParentHandleT a, AttributeHandleT* b);
我需要将这样一个函数的地址传递给迭代器的构造函数,迭代器在这些句柄上进行迭代。由于此函数的具体实现访问外部依赖项,因此我需要模拟它
我想用GoogleMock来模拟这个函数,但我不知道怎么做
这就是我所尝试的:
class IAttributeIterator
{
public:
virtual ReturnT getFirstAttributeHandle(ParentHandleT a, AttributeHandleT* b) = 0;
};
class MockAttributeIterator : public IAttributeIterator
{
public:
MOCK_METHOD2(getFirstAttributeHandle, ReturnT(ParentHandleT a, AttributeHandleT* b));
};
然后像这样:
MockAttributeIterator i;
AttributeIterator iter = AttributeIterator(i.getFirstAttributeHandle);
iter++;
但这不会编译,会出现以下错误:
'MockAttributeInterator::getAttribute':函数调用缺少参数列表;使用“&MockAttributeInterator::getAttribute”创建指向成员的指针
有什么建议吗?没有,您不能将指向成员函数的指针转换为函数指针(这就是编译器所说的) 如果AttributeIterator的构造函数接受指向函数的指针,则需要创建一个伪函数,该函数调用MockAttributeIterator上的getFirstAttributeHandle方法。大概是这样的:
namespace
{
MockAttributeIterator mockObj;
ReturnT FakeHandle(ParentHandleT a, AttributeHandleT* b)
{
mockObj.getFirstAttributeHandle( a, b );
}
}
并将指向FakeHandle的指针传递给AttributeIterator的构造函数
顺便说一句,我刚刚查看了gmock常见问题,这里甚至有解释(链接)
有几件事:
- 上面发布的代码最好放在匿名名称空间中
- 要清除测试之间的期望值,请在设置方法(每个单元测试框架都有一个)中执行以下操作:
void setUp() { ::testing::Mock::VerifyAndClearExpectations( &mockObj ): }
CreateFileW
和CloseHandle
调用
基本思想也在本手册中概述
问题与google mock完全无关,编译器抱怨如下语句:
AttributeIterator iter = AttributeIterator(i.getFirstAttributeHandle);
注意表达式i.getFirstAttributeHandle
,它是一个成员函数调用,因此编译器试图匹配函数签名,但什么也得不到
如果您想将部分应用的函数安全地传递给另一个类,请尝试使用
boost.function/bind
,相反,使用原始函数指针非常危险且容易出错 我将迭代器重命名为上面的AttributeIterator。它是一个输入迭代器。你能发布属性迭代器的构造函数吗?声明足够了,你会把这个代码放在哪里(你的帖子里的代码)?如何在测试之间重置mockObj?您不需要mock类的构造函数和析构函数。顺便说一句,有7个参数的方法=大WTF
AttributeIterator iter = AttributeIterator(i.getFirstAttributeHandle);