使用Google Mock测试类时参数传递编译报错的问题排查
问题分析与修复方案
让我帮你拆解一下代码里的两个核心问题,它们共同导致了这个编译报错:
1. 函数参数传递错误:传了指针而非引用
先看最直接的报错原因:你的AnotherClass::anotherFunction声明是接收**MyClass的非const左值引用**:
void anotherFunction(MyClass&);
但你在测试代码里却传了&mock_myClass——这是一个MyClassMock*类型的指针,和函数要求的MyClass&完全不匹配。你应该直接传递对象本身:mock_myClass,编译器会自动把它转为引用类型。
2. Mock类的继承逻辑完全错了
你提到“原本认为MyClassMock是用来模拟MyClass的”,但看你的代码,MyClassMock继承的是IMyInterface,而不是MyClass:
class MyClassMock : public IMyInterface { ... };
同时AnotherClass::anotherFunction接收的是MyClass&,不是IMyInterface&。这就导致:你的Mock对象和MyClass没有任何继承关系,编译器完全不认为它们是兼容的类型,自然无法绑定引用。
这里有两种正确的修正方向:
方向一:让Mock继承自MyClass(适合MyClass是接口实现类的场景)
首先要确保MyClass本身继承自IMyInterface(这应该是你定义接口的初衷):
// MyClass.h namespace Mynamespace { class MyClass : public IMyInterface { // 这里实现IMyInterface的纯虚函数myFunction }; }
然后修改Mock类,让它继承自MyClass:
// MyClassMock.h #include <gmock/gmock.h> #include "MyClass.h" namespace testing { class MyClassMock : public Mynamespace::MyClass { public: ~MyClassMock() override = default; MyClassMock() = default; MOCK_METHOD0(myFunction, int()); // 覆盖基类的虚函数 }; }
方向二:依赖抽象(更推荐的软件工程实践)
修改AnotherClass::anotherFunction的参数为接口类型,这样代码就不再依赖具体的MyClass,而是依赖抽象的IMyInterface,这也是依赖注入的核心思想:
// AnotherClass.h namespace Mynamespace { class AnotherClass { public: AnotherClass() = default; ~AnotherClass() = default; void anotherFunction(IMyInterface& obj); // 改为接收接口引用 }; }
此时你的MyClassMock继承IMyInterface就完全没问题了,测试代码只需要把参数改成对象本身即可。
修正后的测试代码示例(以方向二为例)
#include <gmock/gmock.h> #include <gtest/gtest.h> #include "MyClassMock.h" #include "AnotherClass.h" using namespace testing; using namespace Mynamespace; TEST(DirectivityParameter, CanInstantiate) { AnotherClass obj_anotherClass; MyClassMock mock_myClass; EXPECT_CALL(mock_myClass, myFunction()) .Times(1) .WillOnce(Return(0)); obj_anotherClass.anotherFunction(mock_myClass); // 直接传对象,不是指针 }
额外小提示
- 记得给Mock类的虚函数加上
override关键字,让编译器帮你检查是否正确覆盖了基类的虚函数,避免拼写错误。 - 确保所有基类的析构函数都是
virtual(你的IMyInterface已经做到了,这点很好),防止内存泄漏。
内容的提问来源于stack exchange,提问作者Simon Symon
相关产品推荐
相关产品推荐

