I'm attempting to test an abstract class using Google Mock. Following the forDummies guide, I've constructed a mock of my class:
我正在尝试使用谷歌Mock测试一个抽象类。在《伪装者指南》之后,我构建了一个模拟我的班级:
AbstractFoo.h
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
MockFoo.h
#include "gmock/gmock.h"
class MockFoo : public AbstractFoo {
public:
MOCK_METHOD2(setSize, void(int w, int h));
}
FooTest.cpp
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
C2660:“:setSize”:函数不接受1个参数。
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?
我的理解是,由于MockFoo扩展AbstractFoo,它应该继承setSize(QSize)方法。然而,情况似乎并非如此。我怎么解决这个问题?
edited for code inaccuracies
编辑的代码错误
2 个解决方案
#1
1
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.
你的问题与googlemock图书馆无关,而是与c++有关。你想要实现的目标是不可能的,因为[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.
您可以通过重命名setSize(const qsize&s)方法来解决这个问题,或者将MockFoo对象转换为AbstractFoo&然后调用这个方法。
You can also take a look into NVI, since that it what it looks like you are trying to do.
你也可以看看NVI,因为它看起来就像你想要做的一样。
#2
0
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.
如果您使用的成员方法是相互重载的版本,那么您很可能会遇到gmock的问题。谷歌mock将每个模拟函数声明为单个的函数对象,当然,当您当然可以重载函数对象时,通常会在functor对象内重载单个操作符()(…)方法。
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
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:
因此,现在对setSize(w,h)的每个调用都指向您的mocked_setSize(w,h)方法。这意味着,现在您必须在单元测试中执行以下操作:
MockFoo.cpp
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.
这将避免在内部使用谷歌mock,将生成一个对象,该对象具有您要声明的方法的名称。
#1
1
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.
你的问题与googlemock图书馆无关,而是与c++有关。你想要实现的目标是不可能的,因为[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.
您可以通过重命名setSize(const qsize&s)方法来解决这个问题,或者将MockFoo对象转换为AbstractFoo&然后调用这个方法。
You can also take a look into NVI, since that it what it looks like you are trying to do.
你也可以看看NVI,因为它看起来就像你想要做的一样。
#2
0
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.
如果您使用的成员方法是相互重载的版本,那么您很可能会遇到gmock的问题。谷歌mock将每个模拟函数声明为单个的函数对象,当然,当您当然可以重载函数对象时,通常会在functor对象内重载单个操作符()(…)方法。
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
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:
因此,现在对setSize(w,h)的每个调用都指向您的mocked_setSize(w,h)方法。这意味着,现在您必须在单元测试中执行以下操作:
MockFoo.cpp
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.
这将避免在内部使用谷歌mock,将生成一个对象,该对象具有您要声明的方法的名称。