独望枫

人在尘世间,有缘自相见,变化千千万,未开窍,已迷恋
posts - 45, comments - 0, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

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

#define FRIEND_TEST(test_case_name, test_name)\

friend class test_case_name##_##test_name##_Test

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

 

继续使用前文使用到的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);

};

 

下面来看看具体如何实施。

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

}

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

 

面对这个问题,第一,我们可以先尝试应用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"

最后,运行测试用例,成功运行

由于需要改动到非测试的源码,而我们工程源码中不一定有包含到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

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理