如何在GTest中Mock外部函数wfdEnumerateDevices以测试tt_init_device
两种Mock全局函数
wfdEnumerateDevices的实现方案 方法1:接口封装依赖(推荐,符合代码可维护性原则)
步骤1:定义抽象接口类
把全局函数包装成抽象接口,让业务类依赖接口而非具体实现:
class WfdDeviceEnumerator { public: virtual ~WfdDeviceEnumerator() = default; virtual bool enumerateDevices(void* a, int b, void* c) = 0; };
步骤2:实现生产环境的真实调用类
在业务代码中,实现接口并调用真实的wfdEnumerateDevices:
class RealWfdDeviceEnumerator : public WfdDeviceEnumerator { public: bool enumerateDevices(void* a, int b, void* c) override { return wfdEnumerateDevices(a, b, c); } };
步骤3:修改业务类的依赖方式
让FusaTelltaleClientAppTh通过构造函数注入接口实例,默认使用真实实现:
class FusaTelltaleClientAppTh { public: FusaTelltaleClientAppTh(int id, const std::string& name, std::unique_ptr<WfdDeviceEnumerator> enumerator = std::make_unique<RealWfdDeviceEnumerator>()) : id_(id), name_(name), enumerator_(std::move(enumerator)) {} WFDErrorCode tt_init_device(void) { // ... 原有逻辑 bool value = enumerator_->enumerateDevices(NULL, 0, NULL); // ... 根据value处理后续逻辑并返回对应错误码 } private: int id_; std::string name_; std::unique_ptr<WfdDeviceEnumerator> enumerator_; };
步骤4:编写Google Mock类
用Google Mock创建接口的Mock实现:
#include <gmock/gmock.h> class MockWfdDeviceEnumerator : public WfdDeviceEnumerator { public: MOCK_METHOD3(enumerateDevices, bool(void*, int, void*)); };
步骤5:编写测试用例
注入Mock对象并设置期望返回值:
TEST_F(FusaAppTh, Sample_Success_WhenEnumerateReturnsTrue) { auto mockEnumerator = std::make_unique<MockWfdDeviceEnumerator>(); // 设置调用参数和返回值期望 EXPECT_CALL(*mockEnumerator, enumerateDevices(NULL, 0, NULL)) .WillOnce(testing::Return(true)); FusaTelltaleClientAppTh AppThObj(1, "abc", std::move(mockEnumerator)); EXPECT_EQ(WFD_ERROR_NONE, AppThObj.tt_init_device()); } TEST_F(FusaAppTh, Sample_Error_WhenEnumerateReturnsFalse) { auto mockEnumerator = std::make_unique<MockWfdDeviceEnumerator>(); EXPECT_CALL(*mockEnumerator, enumerateDevices(NULL, 0, NULL)) .WillOnce(testing::Return(false)); FusaTelltaleClientAppTh AppThObj(1, "abc", std::move(mockEnumerator)); // 根据实际业务逻辑,替换为对应的错误码 EXPECT_EQ(WFD_ERROR_DEVICE_NOT_FOUND, AppThObj.tt_init_device()); }
方法2:直接Mock全局函数(适用于无法修改业务代码的场景)
步骤1:在测试文件中重定义全局函数
利用C++链接规则,让测试中的函数覆盖外部库的实现:
#include <gmock/gmock.h> // 声明全局函数的Mock包装 testing::MockFunction<bool(void*, int, void*)> mockWfdEnumerateDevices; // 重定义全局函数,转发到Mock对象 bool wfdEnumerateDevices(void* a, int b, void* c) { return mockWfdEnumerateDevices.Call(a, b, c); }
步骤2:编写测试用例
直接设置Mock函数的返回期望:
TEST_F(FusaAppTh, Sample_Success_WhenEnumerateReturnsTrue) { EXPECT_CALL(mockWfdEnumerateDevices, Call(NULL, 0, NULL)) .WillOnce(testing::Return(true)); FusaTelltaleClientAppTh AppThObj(1, "abc"); EXPECT_EQ(WFD_ERROR_NONE, AppThObj.tt_init_device()); } TEST_F(FusaAppTh, Sample_Error_WhenEnumerateReturnsFalse) { EXPECT_CALL(mockWfdEnumerateDevices, Call(NULL, 0, NULL)) .WillOnce(testing::Return(false)); FusaTelltaleClientAppTh AppThObj(1, "abc"); EXPECT_EQ(WFD_ERROR_DEVICE_NOT_FOUND, AppThObj.tt_init_device()); }
注意事项
- 方法1遵循依赖倒置原则,代码扩展性和可维护性更强,优先推荐。
- 方法2需要确保测试代码的链接优先级高于外部库,可能需要调整编译脚本的链接顺序。
- 测试环境需提前配置好Google Test和Google Mock库。
内容的提问来源于stack exchange,提问作者Kiran JP
相关产品推荐
相关产品推荐

