# cpp-stub-ext **Repository Path**: clauszy/cpp-stub-ext ## Basic Information - **Project Name**: cpp-stub-ext - **Description**: 对单元测试打桩工具cpp-stub的扩展,用于支持更多的功能 - **Primary Language**: C++ - **License**: MIT - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 8 - **Forks**: 6 - **Created**: 2020-11-30 - **Last Updated**: 2025-06-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # `cpp-stub-ext` # 介绍 基于`cpp-stub`的功能扩展模块,提供更加丰富,方便的功能。 更加高效地在单元测试中打桩。 基于`Linux` 系统与 `gcc/g++`编译器开发(其他平台与编译器未做测试) # 安装教程 1. 在[Github](https://github.com/coolxv/cpp-stub)或者[Gitee](https://gitee.com/coolxv/cpp-stub)下载`cpp-stub`; 2. 将`cpp-stub-ext`与`cpp-stub`一起导入工程; 3. **修改`cpp-stub`的`stub.h`文件,将`Stub`类的私用函数和变量修改为保护型。** # 特性 - 支持使用`lamda`函数打桩 - 便捷地获取虚函数地址 1. 支持`gcc/g++` - 更多特性开发中... # 使用说明 ## 使用`lamda`函数打桩 使用`lamda`函数作为打桩函数,需调专用接口`StubExt::set_lamda`。 `lamda`函数可以使用参数和无参数: 1. 为常规函数打桩,`lamda`有参数时`lamda`函数的参数列表必须与被打桩的函数参数一致。 2. 为成员函数打桩,`lamda`有参数时`lamda`函数的第一个参数必须为该类的指针,接着是该成员函数的参数列表。 3. 为常规函数打桩,`lamda`无参数可直接使用。 4. 为成员函数打桩,`lamda`无参数可直接使用。 ### 示列 - 为常规函数打桩,使用参数 ```c++ #include "stubext.h" using namespace stub_ext; int test(){return 0;} int ret_test(int a){return a;} static int add_test(int a ,int b){return a + b;} int main(int argc, char *argv[]) { int dd = -1; StubExt st; st.set_lamda(&test,[&dd](){dd = 9;return dd;}); st.set_lamda(&ret_test,[&dd](int a){dd = 9 + a;return dd;}); st.set_lamda(&add_test,[&dd](int a, int b){dd = 9 + a - b;return dd;}); int r1 = test(); int r2 = ret_test(2); int r2 = add_test(1,2); return 0; } ``` - 为常规函数打桩,不使用参数 ```c++ #include "stubext.h" using namespace stub_ext; int test(){return 0;} int ret_test(int a){return a;} static int add_test(int a ,int b){return a + b;} int main(int argc, char *argv[]) { int dd = -1; StubExt st; st.set_lamda(&test,[&dd](){dd = 9;return dd;}); st.set_lamda(&ret_test,[&dd](){dd = 9;return dd;}); st.set_lamda(&add_test,[&dd](){dd = 9;return dd;}); int r1 = test(); int r2 = ret_test(2); int r2 = add_test(1,2); return 0; } ``` - 为成员函数打桩,使用参数 ```c++ #include "stubext.h" using namespace stub_ext; class Test { public: int test(){return m;} int ret_test(int a) const {return m + a;} int add_test(int a ,int b) {return m + a + b;} private: int m = 1; }; int main(int argc, char *argv[]) { int dd = -1; StubExt st; st.set_lamda(ADDR(Test,test),[&dd](Test *t){dd = 5; return dd;}); st.set_lamda(ADDR(Test,ret_test),[&dd](Test*,int a){dd = 5 + a; return dd;}); st.set_lamda(ADDR(Test,add_test),[&dd](Test*,int a, int b){dd = 5 + a - b; return dd;}); Test t; int r1 = t.test(); int r2 = t.ret_test(2); int r2 = t.add_test(1,2); return 0; } ``` - 为成员函数打桩,不使用参数 ```c++ #include "stubext.h" using namespace stub_ext; class Test { public: int test(){return m;} int ret_test(int a) const {return m + a;} int add_test(int a ,int b) {return m + a + b;} private: int m = 1; }; int main(int argc, char *argv[]) { int dd = -1; StubExt st; st.set_lamda(ADDR(Test,test),[&dd](){dd = 5; return dd;}); st.set_lamda(ADDR(Test,ret_test),[&dd](){dd = 5; return dd;}); st.set_lamda(ADDR(Test,add_test),[&dd](){dd = 5; return dd;}); Test t; int r1 = t.test(); int r2 = t.ret_test(2); int r2 = t.add_test(1,2); return 0; } ``` - 为类中的静态函数打桩,使用参数 ```c++ #include "stubext.h" using namespace stub_ext; class Test { public: static int sub_test(int a ,int b) {return a - b;} }; int main(int argc, char *argv[]) { int dd = -1; StubExt st; st.set_lamda(ADDR(Test,sub_test),[&dd](int a, int b){dd = 5 - a - b; return dd;}); Test t; int r1 = t.sub_test(1,2); int r2 = Test::sub_test(1,2); return 0; } ``` - 为类中的静态函数打桩,不使用参数 ```c++ #include "stubext.h" using namespace stub_ext; class Test { public: static int sub_test(int a ,int b) {return a - b;} }; int main(int argc, char *argv[]) { int dd = -1; StubExt st; st.set_lamda(ADDR(Test,sub_test),[&dd](){dd = 5; return dd;}); Test t; int r1 = t.sub_test(1,2); int r2 = Test::sub_test(1,2); return 0; } ``` ## 虚函数地址 使用`VADDR()`便捷地获取虚函数地址。 由于功能实现采用的`gcc/g++`的转换方法,目前应该只支持`gcc/g++`编译器 ### 示例 ```c++ #include "stubext.h" using namespace stub_ext; class Test { public: virtual int test() {return 0;} }; class TestB : public Test { public: virtual int test() {return 1;} }; static int foo_stub() { return 9; } int main(int argc, char *argv[]) { int dd = -1; StubExt st; st.set_lamda(VADDR(Test,test),[&dd](){dd = 5; return dd;}); st.set(VADDR(TestB,test),&foo_stub); Test *t1 = new Test; Test *t2 = new TestB; int r1 = t1->test(); int r2 = t2->test(); delete t1; delete t2; return 0; } ``` # 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request