如何使用gMock为FunctionCall内部调用的GettingNumberFromSystemState打桩
使用gMock模拟
GettingNumberFromSystemState的实现方案 gMock原生支持类成员函数模拟,要模拟全局函数可通过两种常用方案实现:
方案1:依赖注入适配(推荐,可维护性最高)
仅需对生产代码做极少量改动,即可实现稳定的Mock能力:
- 第一步:定义抽象接口层,包装系统状态相关操作
class SystemStateInterface { public: virtual ~SystemStateInterface() = default; virtual int GettingNumberFromSystemState() = 0; }; // 生产环境默认实现,保留原有业务逻辑 class ProductionSystemState : public SystemStateInterface { public: int GettingNumberFromSystemState() override { // 原有的系统状态读取逻辑不变 } };
- 第二步:修改
FunctionCall实现,注入接口依赖
// 全局默认使用生产环境实现,测试时可动态替换 std::unique_ptr<SystemStateInterface> g_system_state = std::make_unique<ProductionSystemState>(); bool FunctionCall() { int number = g_system_state->GettingNumberFromSystemState(); if(number > A_CERTAIN_VALUE) { return true; }else{ return false; } }
- 第三步:编写Mock类继承抽象接口
#include <gmock/gmock.h> class MockSystemState : public SystemStateInterface { public: MOCK_METHOD(int, GettingNumberFromSystemState, (), (override)); };
- 第四步:编写测试用例,自定义返回值
TEST_F(testing, FunctionCall返回True当数值大于阈值) { // 替换全局实例为Mock对象 MockSystemState mock_state; g_system_state.reset(&mock_state); // 指定Mock返回值大于阈值,预期返回true EXPECT_CALL(mock_state, GettingNumberFromSystemState()) .WillOnce(testing::Return(A_CERTAIN_VALUE + 1)); bool result = FunctionCall(); EXPECT_EQ(true, result); // 测试结束后释放所有权,避免野指针 g_system_state.release(); } TEST_F(testing, FunctionCall返回False当数值小于等于阈值) { MockSystemState mock_state; g_system_state.reset(&mock_state); // 指定Mock返回值小于阈值,预期返回false EXPECT_CALL(mock_state, GettingNumberFromSystemState()) .WillOnce(testing::Return(A_CERTAIN_VALUE - 1)); bool result = FunctionCall(); EXPECT_EQ(false, result); g_system_state.release(); }
方案2:非侵入式链接期Mock(无需修改生产代码)
如果不允许改动生产代码的逻辑,可使用gMock 1.11及以上版本的全局函数Mock特性,通过链接替换实现:
- 第一步:定义全局Mock函数,不需要修改原有生产代码的声明
#include <gmock/gmock.h> MOCK_FUNCTION(int, GettingNumberFromSystemState, ());
- 第二步:编译测试目标时,排除原
GettingNumberFromSystemState的实现文件,避免链接冲突,测试用例写法如下:
TEST_F(testing, testingFunctionCall) { // 直接指定全局Mock函数的返回值 EXPECT_CALL(*testing::MockFunction<int()>::GetHolder("GettingNumberFromSystemState"), Call()) .WillOnce(testing::Return(A_CERTAIN_VALUE + 1)); bool result = FunctionCall(); EXPECT_EQ(true, result); }
注意:该方案依赖特定版本gMock特性,兼容性低于依赖注入方案
内容的提问来源于stack exchange,提问作者Colin Harker
相关产品推荐
相关产品推荐

