Question

I'm attempting to test an abstract class using Google Mock. Following the forDummies guide, I've constructed a mock of my class:

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
}

The marked line produces the following compiler error:

C2660: 'MockFoo::setSize' : function does not take 1 arguments

My understanding is that since MockFoo extends AbstractFoo, it should inherit the setSize(QSize) method. However, this does not appear to be the case. How can I fix this?

edited for code inaccuracies

Was it helpful?

Solution 2

The signature of your method in the mock class is wrong :

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

and the base class has the method with this signature :

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

I am not sure which compiler you are using, but that should be a compiler error.

Fix the signature, and the error should go away :

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

Additionally,

class MockFoo : AbstractFoo

should be

class MockFoo : public AbstractFoo

Your problem has nothing to do with googlemock library - but rather with c++. What you are trying to achieve is not possible because of [class.virtual]/1.

Next example demonstrates the same problem :

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

You can solve this issue by renaming setSize(const QSize& s) method, or by casting MockFoo object to AbstractFoo& and then calling this method.

You can also take a look into NVI, since that it what it looks like you are trying to do.

OTHER TIPS

if you are messing around with member methods that are overloaded versions of each other, then you are likely to run into problems with gmock. Google mock declares each mocked function as individual functor objects and while you of course can overload functor objects, what you will normally do is overloading the individual operator()(...) methods inside the functor object.

I usually get around this problem by declaring a wrapper mock function and then call that from my overloaded function. The header will then look like this:

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

So now every call to setSize(w,h) is directed to your mocked_setSize(w,h) method. This means that now you will have to do the following in your unit test:

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.
}

This will avoid that google mock internally will generate an object with the name of the method you are trying to declare.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top