protected函数如何单元测试

protected函数如何单元测试

类的protected函数相比public函数,测试套件定义的对象无法直接访问,gtest提供了一个宏FRIENT_TEST,这个宏定义如下:

#define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test

可以见到其实现,主要是将测试用例名及测试名链接起来当成是被测类的友元类(gtest在运行时会自动将每个用例生成一个类进行运行)。

继续使用前文 public函数如何单元测试 使用到的model作为例子,此处增加一个protected的成员方法Factorial(该方法同样借用自gtest官方示例):

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

**protected:**
    **int Factorial(int n);**
};

下面来看看protected函数具体如何实施单元测试。

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宏定义想要测试的类的protected函数的测试用例

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

此时运行的话,系统会报错:
image.png

面对这个问题,第一,我们可以先尝试应用gtest提供的宏FRIEND_TEST
首先,我们需要在被测类model中,使用FRIEND_TEST将我们需要使用到的testname进行注册

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

protected:
    int Factorial(int n);

**FRIEND_TEST(modelTest, Negative);**
**FRIEND_TEST(modelTest, Zero);**
**FRIEND_TEST(modelTest, Positive);**
};

其次,我们需要将FRIEND_TEST宏定义的头文件包含进来

#include "gtest/gtest_prod.h"

最后,运行测试用例,成功运行
image.png

但是由于需要改动到非测试的源码,而我们工程源码中不一定有包含到gtest相关的内容,很有可能会导致源工程编译出错,所以我们可以在*.pro文件中,增加一个宏定义

DEFINES += UT

然后再在被测试类model中,对新增的FRIEND_TEST及其头文件,可以使用预编译处理

#ifdef UT
#include "gtest/gtest_prod.h"
#endif  // UT

#ifdef UT
FRIEND_TEST(modelTest, Negative);
FRIEND_TEST(modelTest, Zero);
FRIEND_TEST(modelTest, Positive);
#endif  // UT

这样就可以使得源工程编译不受单元测试新增处理的影响。

但是

这里要说但是了……这样的测试会改动到我们的源码,是侵入式的,很令人不爽。所以这里可以使用一种更取巧的方式:

#ifdef UT
#define protected public
#define private public
#endif  // UT

简单、直接、粗暴……但有效,而且修改不影响到原有类,可以统一在某个都引用到的头文件中,那么一次添加,后人乘凉啊

对应的demo源码,请点击 protectedFunc

也可扫码关注博主同名公众号"不解之榬",回复 “protected” 获取
不解之榬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值