在Google Mock上调用重载函数

时间:2013-07-09 05:57:47

标签: c++ googlemock

我正在尝试使用Google Mock测试抽象类。在forDummies指南之后,我构建了一个模拟我的课程:

AbstractFoo.h

class AbstractFoo {
public:
  virtual void setSize(int w, int h) = 0;
  void setSize(const QSize& s); // implemented as calling above function
}

MockFoo.h

#include "gmock/gmock.h"
class MockFoo : public AbstractFoo {
public:
  MOCK_METHOD2(setSize, void(int w, int h));
}

FooTest.cpp

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "MockFoo.h"

TEST(AbstractFoo, MethodSetSize) {
  MockFoo foo;
  EXPECT_CALL(foo, setSize(5, 5)).Times(1);
  foo.setSize(QSize(5, 5)); // this line produces compiler error
}

标记的行会产生以下编译器错误:

  

C2660:'MockFoo :: setSize':函数不带1个参数

我的理解是,由于MockFoo扩展AbstractFoo,它应该继承setSize(QSize)方法。但是,情况似乎并非如此。我该如何解决这个问题?

为代码不准确而编辑的

2 个答案:

答案 0 :(得分:2)

模拟类中方法的签名是错误的:

MOCK_METHOD2(setSize, bool(int w, int h));

并且基类具有带此签名的方法:

virtual void setSize(int w, int h) = 0;

我不确定您使用的是哪种编译器,但这应该是编译器错误。

修复签名,错误应该消失:

MOCK_METHOD2(setSize, void(int w, int h));

此外,

class MockFoo : AbstractFoo

应该是

class MockFoo : public AbstractFoo

您的问题与googlemock库无关 - 而是与c ++无关。由于[class.virtual] / 1,您无法实现的目标。

下一个示例演示了同样的问题:

struct A
{
    A(int h,int l):x(h),y(l){}
    int x; int y;
};

class AbstractFoo {
public:
    virtual void setSize(int w, int h) = 0;
    void setSize(const A& s){setSize(s.x,s.y);}
};

class MockFoo : public AbstractFoo
{
public:
    void setSize(int , int ){}
};

int main()
{
    MockFoo f;
    A a(5,5);

    f.setSize( a );
}

您可以通过重命名setSize(const QSize& s)方法或将MockFoo对象转换为AbstractFoo&然后调用此方法来解决此问题。

您还可以查看NVI,因为它看起来就像您要做的那样。

答案 1 :(得分:1)

如果你正在搞乱彼此重载版本的成员方法,那么你可能会遇到gmock的问题。 Google模拟将每个模拟函数声明为单独的仿函数对象,当然您可以重载仿函数对象,您通常会在仿函数对象中重载单个operator()(...)方法。

我通常通过声明一个包装器模拟函数来解决这个问题,然后从我的重载函数中调用它。标题将如下所示:

<强> MockFoo.h

#include "gmock/gmock.h"
class MockFoo : public AbstractFoo {
  public:
    void setSize(int w, int h) {
      mocked_setSize(w, h);  ///< workaround to call the mocked setSize instead.
    }

    MOCK_METHOD2(mocked_setSize, void(int w, int h));
}

现在,对setSize(w,h)的每次通话都会定向到您的mocked_setSize(w,h)方法。这意味着现在您必须在单元测试中执行以下操作:

<强> MockFoo.cpp

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "MockFoo.h"

TEST(AbstractFoo, MethodSetSize) {
  MockFoo foo;
  EXPECT_CALL(foo, mocked_setSize(5, 5)).Times(1);
  foo.setSize(QSize(5, 5)); ///< now this should compile cleanly.
}

这样可以避免google mock在内部生成一个对象,其中包含您要声明的方法的名称。