通过Gtest访问C++静态、私有、保护变量和方法

admin 2024年7月4日08:24:05评论1 views字数 7278阅读24分15秒阅读模式

1,通常情况

在工作目录主目录下建立目录src

进入src下建立TestAll.cpp测试主文件.

#include "gtest/gtest.h"#include <iostream>using namespace std;int main(int argc,char* argv[]){        testing::GTEST_FLAG(output) = "xml:";     //若要生成xml结果文件        testing::InitGoogleTest(&argc,argv);      //初始化        return RUN_ALL_TESTS();                   //跑单元测试}

建立参数化文件CallArgs.h

//CallArgs.cpp   #include <gtest/gtest.h>class CallArgs{public:  CallArgs(int haspramx,int hasprama,int haspramb, float hasresult);      int pramx();  int prama();  int pramb();  float result();private:  int _hasPramx;  int _hasPrama;  int _hasPramb;  float _hasResult; };

和CallArgs.cpp

//CallArgs.cpp#include <gtest/gtest.h>#include "CallArgs.h"  CallArgs::CallArgs(int haspramx,int hasprama,int haspramb, float hasresult):     _hasPramx(haspramx),_hasPrama(hasprama),_hasPramb(haspramb),_hasResult(hasresult){}      int CallArgs::pramx(){ return _hasPramx;}  int CallArgs::prama(){ return _hasPrama;}  int CallArgs::pramb(){ return _hasPramb;}  float CallArgs::result(){return _hasResult;}  int _hasPramx;  int _hasPrama;  int _hasPramb;  float _hasResult;

接下来建立被测文件的头文件process.h

//process.h  #ifndef PROCESS_H  #define PROCESS_H  class Process {  public:      int x;    Process();    int process(int a, int b);  };  #endif

被测文件很简单,包括类变量x和类函数Process,默认为public。本文通过改变类变量x和类函数Process的属性来介绍如何通过Gtest访问C++静态、私有、保护变量和方法。建立被测文件的实现方法,process.cpp。

#include <stdio.h>#include "process.h"int x;Process::Process(){}int Process::process(int a, int b){       if ((a>1) && (b==0)){              Process::x=Process::x/a;        }       if((a==2) || (Process::x>1)){              Process::x=Process::x+1;        }       return Process::x;}

在下面的介绍中process.cpp不会做任何变化。下面来建立gtest的测试代码,processTest.cpp。

// ProcessTest.cpp  #include "process.h"#include "../../src/CallArgs.h"   #include <gtest/gtest.h> class ProcessTestWithTestP:public ::testing::TestWithParam{};INSTANTIATE_TEST_CASE_P(VOIP, ProcessTestWithTestP, ::testing::Values(    CallArgs{1,2,0,1},     CallArgs{0,4,0,0},    CallArgs{1,2,1,2},    CallArgs{0,1,1,0}));TEST_P(ProcessTestWithTestP,BasicTest){   CallArgs args = GetParam();   Process p;   p.x = args.pramx();   EXPECT_FLOAT_EQ(p.process(args.prama(),args.pramb()),args.result());    }

ProcessTestWithTestP为测试类,为了达到被测程序的100%路径覆盖,设计4组测试用例,在Gtest中正好可以使用TEST_P参数化来进行测试。

INSTANTIATE_TEST_CASE_P来初始化这4组测试用例的测试数据。

通过

TEST_P(ProcessTestWithTestP,BasicTest)

来实现。

通过

g++ process.h process.cpp processTest.cpp ../../src/AllTest.cpp ../../src/ CallArgs.cpp.h ../../src/ CallArgs.cpp.cpp -o process -lgtest -lgmock -lpthread -std=c++14

来编译,然后通过

./process

来运行

2,静态变量和静态方法

在下面介绍中如何调用静态变量和静态方法,静态变量和静态方法比较简单,一般直接调用就可以。

2.1静态变量

修改process.h文件。

//process.h  #ifndef PROCESS_H  #define PROCESS_H  extern int x; class Process {  public:     Process();    int process(int a, int b);  };  #endif

通过extern int x;将x变为静态全局变量,在测试文件procesTest.cpp,可以直接通过x来访问。

TEST_P(ProcessTestWithTestP,BasicTest){   CallArgs args = GetParam();   Process p;   x = args.pramx();   EXPECT_FLOAT_EQ(p.process(args.prama(),args.pramb()),args.result());}

2.2静态方法

修改process.h文件。

//process.h  #ifndef PROCESS_H      #define PROCESS_H  extern int x; class Process {  public:     Process();    static int process(int a, int b);  };  #endif

通过static int process(int a, int b);将process(int a, int b)变为静态方法,在测试文件procesTest.cpp,仍旧通过p.process()来访问。

TEST_P(ProcessTestWithTestP,BasicTest){   CallArgs args = GetParam();   Process p;   x = args.pramx();   EXPECT_FLOAT_EQ(p.process(args.prama(),args.pramb()),args.result());}

3,保护变量和保护方法

保护变量和保护方法,在测试文件procesTest.cpp定义class ProcessTest类的时候将继承的Process类改为public属性。

3.1保护变量

修改process.h文件。

//process.h  #ifndef PROCESS_H  #define PROCESS_H  class Process {  public:     Process();    int process(int a, int b);  protected:     int x;};  #endif

将int x;放在protected下,在测试文件procesTest.cpp定义class ProcessTest类的时候将继承的Process类改为public属性。

class ProcessTest : public ::testing::TestWithParam, public Process{};

然后在测试文件中直接使用x和process()方法。

class ProcessTest : public ::testing::TestWithParam, public Process{    };TEST_P(ProcessTest,BasicTest){   CallArgs args = GetParam();   x = args.pramx();   EXPECT_FLOAT_EQ(process(args.prama(),args.pramb()),args.result());}

3.2保护方法

修改process.h文件。

//process.h  #ifndef PROCESS_H  #define PROCESS_H  class Process {  public:     int x;    Process();protected:     int process(int a, int b);  };  #endif  

将int process(int a, int b);放在protected下,同样在测试文件procesTest.cpp定义class ProcessTest类的时候将继承的Process类改为public属性。

class ProcessTest : public ::testing::TestWithParam, public Process{};TEST_P(ProcessTest,BasicTest){   CallArgs args = GetParam();   x = args.pramx();   EXPECT_FLOAT_EQ(process(args.prama(),args.pramb()),args.result());}

4,私有变量和私有方法

访问私有变量和私有方法比较复杂,不太推荐,因为它会破坏类的封装。但是实现方法基本相同。

1)在被测类头文件中加入

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

2)在被测类头文件中预先声明被测类

class 被测类;

3)在被测类头文件中类定义中加入

FRIEND_TEST(被测类, TEST_P);

4)在测试类文件processTest.cpp开始加入:

#include: <cstddef>:定义常用常量

5)在测试类文件processTest.cpp中将测试类定义为保护属性。

class ProcessTest : public ::testing::TestWithParam,protected Process{};

6)使用第3)步定义的测试方法

TEST_P(被测类, TEST_P)

4.1私有变量

修改process.h文件。

//process.h  #ifndef PROCESS_H  #define PROCESS_H #define FRIEND_TEST(test_case_name, test_name)friend class test_case_name##_##test_name##_Test class ProcessTest;  class Process {  public:     Process();    int process(int a, int b);    private:     int x;    FRIEND_TEST(ProcessTest, TEST_P);};  #endif

将int x放在private下

修改processTest.cpp文件

//ProcessTest.cpp  #include "process.h" #include "../../../src/CallArgs.h"  #include <gtest/gtest.h> #include <cstddef>class ProcessTest : public ::testing::TestWithParam,protected Process{};INSTANTIATE_TEST_CASE_P(VOIP, ProcessTest, testing::Values(    CallArgs{1,2,0,1},     CallArgs{0,4,0,0},    CallArgs{1,2,1,2},    CallArgs{0,1,1,0}    ));TEST_P(ProcessTest, TEST_P){   CallArgs args = GetParam();   Process p;   p.x = args.pramx();   EXPECT_FLOAT_EQ(p.process(args.prama(),args.pramb()),args.result());}

4.2私有方法

修改process.h文件

//process.h  #ifndef PROCESS_H  #define PROCESS_H #define FRIEND_TEST(test_case_name, test_name)friend class test_case_name##_##test_name##_Test class ProcessTest;  class Process {  public:         Process();    int x;private:     int process(int a, int b);    FRIEND_TEST(ProcessTest, TEST_P);};  #endif

将int process(int a, int b);放在private下

修改processTest.cpp文件同私有变量。

//ProcessTest.cpp  #include "process.h"  #include "../../../src/CallArgs.h" #include <gtest/gtest.h> #include <cstddef>class ProcessTest : public ::testing::TestWithParam,protected Process{};INSTANTIATE_TEST_CASE_P(VOIP, ProcessTest, testing::Values(    CallArgs{1,2,0,1},         CallArgs{0,4,0,0},    CallArgs{1,2,1,2},    CallArgs{0,1,1,0}));TEST_P(ProcessTest, TEST_P){   CallArgs args = GetParam();   Process p;   p.x = args.pramx();   EXPECT_FLOAT_EQ(p.process(args.prama(),args.pramb()),args.result());}

另外,还可以通过公共接口类来访问私有和保护对象和方法。

5,通过公共接口类来访问私有和保护对象和方法

5.1 通过公共接口类来访问私有对象和方法

MyClass.h

// MyClass.hclass MyClass {private:    int value;    void Increment() { // 私有方法            value++;    }public:    MyClass() : value(0) {}    void PerformIncrement() { // 公共方法        Increment();    }    int GetValue() const { // 公共方法,用于获取私有成员的值        return value;    }};

MyClass.h定义了私有类value和私有方法Increment()。

通过公共方法PerformIncrement()来调用私有方法Increment();

通过公共方法GetValue()来获取私有成员value的值。

建立测试程序MyClassTest.cpp

// MyClassTest.cpp#include "MyClass.h"#includeTEST(MyClassTest, IncrementTest) {    MyClass obj;    obj.PerformIncrement(); // 调用公共方法来间接调用私有方法        EXPECT_EQ(1, obj.GetValue()); // 验证私有方法的行为}

5.2通过公共接口类来访问保护对象和方法

同样也可以通过公共接口类来访问保护对象和方法。

// MyClass.hclass MyClass {protected:    int value;    void ProtectedMethod() { // 保护方法        value = 42;    }public:    MyClass() : value(0) {}    void CallProtectedMethod() { // 公共方法,调用保护方法        ProtectedMethod();    }    int GetValue() const { // 公共方法,用于获取保护成员的值        return value;    }};

MyClass.h定义了int value;保护变量和void ProtectedMethod()保护方法。    

通过公共方法CallProtectedMethod()调用保护方法;

通过公共方法GetValue()获取保护成员的值。

建立测试程序MyClassTest.cpp

//MyClassTest.cpp#include "MyClass.h"#includeTEST(MyClassTest, ProtectedMethodTest) {    MyClass obj;    obj.CallProtectedMethod(); // 调用公共方法来间接调用保护方法    EXPECT_EQ(42, obj.GetValue()); // 验证保护方法的行为}

这里介绍了如何通过Gtest访问C++静态、私有、保护变量和方法,下一节将介绍如何通过JUnit访问Java静态、私有、保护变量和方法。

原文始发于微信公众号(啄木鸟软件测试):通过Gtest访问C++静态、私有、保护变量和方法

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月4日08:24:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   通过Gtest访问C++静态、私有、保护变量和方法https://cn-sec.com/archives/2916769.html

发表评论

匿名网友 填写信息