我有一个类,例如ClassA,它具有一些公共功能和私有功能。 公共功能又将私有功能分类。 现在,我的目的是通过公共功能测试私有功能。 对于Public函数,我试图调用原始实现,对于私有方法,我试图创建一个Mock函数。
我的A类是这样的,
class ClassA {
public:
string getName(string key) {
int value = 2;
int code = getCode(value);
if(code != 2)
cout<<"Error";
else
return "XYZ";
}
private:
int getCode(int value) {
if(value == 2)
return 2;
else
return -1;
}
};
现在我有一个像这样的ClassA模拟了,
class MockA : public ClassA {
public:
MOCK_METHOD1(getName,string(string key)); //Mock for public method
MOCK_METHOD1(getCode,int(int value))l //Mock for private method
}
这是我的GoogleTest测试用例,
TEST(ClassATest, Test1)
{
MockA a;
Class a1;
EXPECT_CALL(a,getCode()).Times(1).WillOnce(Return(2));
EXPECT_CALL(a,getName()).Times(1).WillOnce(Return(Invoke(&a1,
ClassA::getName());
}
如您所见,对于私有方法,我正在使用模拟,对于公共方法,我正在使用Invoke并调用原始实现。
现在,当我编译这段代码时,我得到一个错误,
实际函数调用计数与EXPECT_CALL(a,getCode())不匹配。 预期:将被调用一次 实际:从未致电-不满意和主动
现在,当我尝试对getCode()使用原始实现时也是如此,
EXPECT_CALL(a,getCode()).Times(1).WillOnce(Return(Invoke(&a1,
ClassA::getCode());
我收到一个编译错误,说getCode()无法访问,我认为这是预期的。
现在,如果您正在阅读本文,希望您理解我的问题陈述。 我必须通过我通过gtest测试的公共方法,通过传入不同的参数来测试私有方法。
我想模拟github中this文章中所述的私有方法,并为我的公共方法调用原始的生产代码。
我在根本上做错了吗?如果是这样,你们中的任何一个可以为我的用例提供更好的方法。
我尝试了FRIEND_TEST和tbh,我不想在生产代码中进行任何修改。我会尽力而为。
答案 0 :(得分:1)
您正在尝试从ClassA
调用私有方法。除非有一个朋友声明,否则这是不可能的,但是,这并不理想。
问题源于您的测试设计,该测试应调用公共API而不是实现细节。
答案 1 :(得分:0)
最新答案,但是我目前正在研究类似问题,并且看到了这个问题。
在您的示例中,我不确定Invoke()
的用途是什么,但是如果您要尝试做的就是验证对getCode()
的调用并控制其返回值,那么您只会需要嘲笑那个。
您将必须修改生产代码以使私有函数虚拟化,因此,如果这不是一个选择,那么这当然对您不起作用。不过,这似乎是一个相当安全的修改。
class ClassA {
public:
string getName(string key) {
int value = 2;
int code = getCode(value);
if (code != 2)
return "Error";
return "XYZ";
}
private:
virtual int getCode(int value) {
if (value == 2)
return 2;
return -1;
}
};
class MockA : public ClassA {
public:
MOCK_METHOD1(getCode, int(int value));
};
TEST(ClassATest, Test1)
{
MockA mockA;
EXPECT_CALL(mockA, getCode(2)).WillOnce(Return(2));
EXPECT_EQ(mockA.getName("key"), "XYZ");
}