private函数如何单元测试
类的private
函数相比public
函数,测试套件定义的对象无法直接访问;相比protected
函数,亦无法通过 前文(protected函数如何单元测试) 提到的FRIENT_TEST
来使用,那么我们要怎么才能解决这个问题呢?
下面来看看具体如何实施。
1.首先构建测试套件,定义一个继承自testing::Test
的类
class modelTest : public testing::Test {
protected:
};
2.同样需要复写SetUp/TearDown
两个函数
class modelTest : public testing::Test {
protected:
**void SetUp() override {**
**}**
**void TearDown() override {**
**}**
};
3.定义想要测试单元测试需要用到的数据,并在SetUp
进行初始化,在TearDown
中进行清理或析构。
class modelTest : public testing::Test {
protected:
void SetUp() override {
**pm = new model;**
}
void TearDown() override {
**if (pm) {**
**delete pm;**
**pm = NULL;**
**}**
}
**model* pm;**
};
4.通过TEST_F
宏定义想要测试的类的private
函数的测试用例
// Tests factorial of negative numbers.
TEST_F(modelTest, Negative) {
// This test is named "Negative", and belongs to the "FactorialTest"
// test case.
EXPECT_EQ(1, pm->Factorial(-5));
EXPECT_EQ(1, pm->Factorial(-1));
EXPECT_GT(pm->Factorial(-10), 0);
}
// Tests factorial of 0.
TEST_F(modelTest, Zero) {
EXPECT_EQ(1, pm->Factorial(0));
}
// Tests factorial of positive numbers.
TEST_F(modelTest, Positive) {
EXPECT_EQ(1, pm->Factorial(1));
EXPECT_EQ(2, pm->Factorial(2));
EXPECT_EQ(6, pm->Factorial(3));
EXPECT_EQ(40320, pm->Factorial(8));
}
此时运行的话,系统会报错:
PS:请见谅直接使用了前文protected
的函数,这里仅仅将访问权限protected
修改为了private……
class model
{
private:
device* _pdevice;
network* _pnetwork;
public:
model();
~model();
void printmodelinfo();
void printmodelverion();
void printmodeldeviceinfo();
void printmodeldeviceversion();
void printmodeldeviceserial();
void printallinfo();
bool showImg();
bool showData();
bool IsPrime(int n);
private:
int Factorial(int n);
};
面对这个问题,第一,我们可以先使用 [[3-protected函数如何单元测试|前文(protected函数如何单元测试)]] 提到private
宏定义为public
的方式
#ifdef UT
#define protected public
#define private public
#endif // UT
简单、直接、粗暴,有效。
但是这个几行代码虽然简单,但如果有很多个类并且没有一个都被包含了的头文件的话,加起来还是有工作量的。那么可以使用一个python
脚本来执行这个处理,如果使用到了独立脚本进行处理这个事情,则可以有另一个粗暴的方法:
private:
修改为
// private:
单测运行后再次运行脚本将’‘//private:
’‘转为’‘private:
’’
这样后台将在编译前会进行private
的public
处理,编译完成后恢复privated
的访问权限
<<end_unittest.py>>
<<pre_unittest.py>>
附编译前private
处理脚本及编译后private
还原处理的脚本【请到文末的github
连接下载俩脚本】。
当然,官方还有一种方法,需要重构代码,将privated
的函数都转移到一个新建的文件中实现,简称pimpl
,私有实现,详细查看 官方教程。
但是这种方式,如果在前期没考虑到,后期修改成本较高;而第一第二种方案,虽然没第三种优雅,但其成本较低而且不用修改到源工程的功能代码。可以根据实际情况,按需使用。
对应的demo源码,请点击 privateFunc
也可扫码关注博主同名公众号"不解之榬",回复 “private” 获取