我有一个班级,比如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());
}
正如您所看到的,对于私有方法,我使用mock和public方法,我使用Invoke并调用原始实现。
现在,当我编译这段代码时,我收到一个错误,
实际函数调用计数与EXPECT_CALL(a,getCode())不匹配....预期:被调用一次实际:从未调用 - 未满足且处于活动状态
现在当我尝试使用原始的实现来获取getCode()时,
EXPECT_CALL(a,getCode()).Times(1).WillOnce(Return(Invoke(&a1,
ClassA::getCode());
我得到一个编译错误,说getCode()是不可访问的,我认为是预期的。
到现在为止,如果你正在读这篇文章,希望你能理解我的问题陈述。我必须通过传递不同的参数来测试私有方法,通过我通过gtest测试的公共方法。
我想模仿github中的this文章所述的私有方法,并为我的公共方法调用orininal生产代码。
我做了一些根本错误的事吗?如果是这样,你们中的任何人都可以使用更好的方法来处理我的用例
我尝试过FRIEND_TEST和tbh,我不想在我的生产代码中进行任何修改。我会尝试这作为最后的手段。
您正在尝试从ClassA
调用私有方法。这是不可能的,除非有朋友声明,但是,它不是理想的。
问题源于您的测试设计应该调用公共API而不是实现细节。
迟到的答案,但我目前正在研究类似的问题,并看到了这个问题。
在你的例子中,我不太清楚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");
}