C++ GoogleTest中如何为被Mock方法内部调用的Mock方法设置期望
问题原因
你遇到的问题由以下几个错误共同导致:
- Mock逻辑分层错误:如果你注入到Client的
p_service是IStateMachine的纯Mock实现,Mock生成的Run方法默认不会调用真实StateMachine类的Run逻辑,自然不会触发内部的IsTxnValid调用。 - 方法名不匹配:你代码里定义的校验方法是
IsTxnValid,但测试用例的EXPECT_CALL写的是IsTransitionValid,名称不匹配无法识别到调用。 - 参数/调用签名不匹配:你定义的
RunService需要接收std::string& action参数,但测试代码里调用的是无参的x_client->RunService(),同时Run方法的期望匹配参数和实际传入参数也存在不匹配的问题。
解决方案
根据你的测试目标,可以选择以下两种方案:
方案1:仅测试Client的逻辑(不需要验证StateMachine内部实现)
如果你的测试目标只是验证Client的RunService会透传IStateMachine::Run的返回值,不需要关心Run的内部逻辑,直接Mock Run返回false即可:
TEST_F(ClientTest, RunServiceReturnsFalseWhenRunFails) { std::string test_action = "some_action"; // 模拟Run方法调用后返回false EXPECT_CALL(*p_service, Run(test_action)).WillOnce(::testing::Return(false)); // 传入对应参数调用RunService EXPECT_EQ(false, x_client->RunService(test_action)); }
方案2:验证StateMachine内部调用链路
如果你需要同时验证Run会调用IsTxnValid、且IsTxnValid返回false时全链路返回false,需要使用部分Mock(Partial Mock):
- 首先定义继承自
StateMachine的Mock类,只Mock需要打桩的IsTxnValid方法,保留Run的真实实现:
class MockStateMachine : public StateMachine { public: MOCK_METHOD(bool, IsTxnValid, (const std::string& action), (override)); // 不Mock Run方法,走父类的真实实现 };
- 调整测试用例:
TEST_F(ClientTest, RunServiceReturnsFalseWhenTxnInvalid) { std::string test_action = "some_action"; // 构造Mock实例注入到Client auto mock_sm = std::make_unique<MockStateMachine>(); MockStateMachine* p_mock = mock_sm.get(); x_client->service_ = std::move(mock_sm); // 仅设置IsTxnValid的返回期望 EXPECT_CALL(*p_mock, IsTxnValid(test_action)).WillOnce(::testing::Return(false)); // 调用RunService验证返回值 EXPECT_EQ(false, x_client->RunService(test_action)); }
注意事项
- 不要同时Mock
Run方法和期望内部的IsTxnValid调用,Mock的Run会直接返回你设置的值,不会执行真实的内部调用逻辑。 - 如果你不需要严格匹配调用参数,可以用
testing::_通配符替代具体参数值。 - 确保Mock方法的名称、参数列表、const修饰符和原方法完全一致,否则无法匹配到调用。
内容的提问来源于stack exchange,提问作者warrior_monk
相关产品推荐
相关产品推荐

