C++ 使用Google Mocks模拟自由函数

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

我有以下自由函数sig:

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);