Google Mock类未实现引发链接错误及调用验证失败求助
嘿,我来帮你搞定这两个Google Mock的问题——从最开始的链接错误,到后来的EXPECT_CALL未触发,咱们一步步拆解:
一、x86_64架构下的未定义符号链接错误
你最初遇到的链接错误,根源很明确:你的Mock类只声明了构造函数和析构函数,却没有提供实现。Google Mock会自动为MOCK_METHOD标记的虚函数生成实现代码,但像构造、析构这类自定义的非虚成员函数,必须由你自己编写实现,哪怕是空实现也行。
看你最初的Mock类声明:
#include <gmock/gmock.h> #include <IMyInterface.h> namespace testing { class MyClassMock : public IMyInterface { public: ~MyClassMock(); MyClassMock(int, int, int); MOCK_METHOD0(myFunction, void()); }; }
这里的MyClassMock(int, int, int)和~MyClassMock()只有声明,链接器在生成可执行文件时找不到它们的定义,自然会抛出未定义符号的错误。
你后来补充的实现是完全正确的:
namespace testing { MyClassMock::MyClassMock(int a, int b, int c) { } MyClassMock::~MyClassMock() { } }
这部分解决了链接问题,但接下来又遇到了测试断言不通过的新问题。
二、EXPECT_CALL提示“从未被调用”的问题
你的测试代码是这样的:
#include "MyClassMock.h" #include <gmock/gmock.h> #include <gtest/gtest.h> using ::testing::AtLeast; using namespace testing; TEST(MyClassTest, canCallFunction) { MyClassMock mock(0,0,0); EXPECT_CALL(mock, myFunction()) .Times(AtLeast(1)); }
问题其实特别直白:你只给myFunction()设置了调用预期,但从头到尾根本没调用这个方法啊!
EXPECT_CALL的作用是验证某个方法是否按照你预期的次数/方式被调用,它不会自动帮你执行这个方法。要让测试通过,你需要主动调用mock.myFunction(),或者让被测试的业务逻辑去触发这个调用。
方案1:手动调用Mock方法(仅用于验证Mock本身)
如果只是想验证Mock的方法能被正确调用,直接在测试里手动调用即可:
TEST(MyClassTest, canCallFunction) { MyClassMock mock(0,0,0); EXPECT_CALL(mock, myFunction()) .Times(AtLeast(1)); // 主动调用方法,满足预期 mock.myFunction(); }
方案2:通过业务逻辑触发Mock调用(更符合测试场景)
通常我们用Mock是为了模拟依赖,所以正确的做法是把Mock对象注入到被测试的业务类中,让业务逻辑去调用Mock的方法。比如你有一个依赖IMyInterface的业务类:
class MyBusinessClass { public: explicit MyBusinessClass(IMyInterface* dependency) : dep_(dependency) {} void process() { // 业务逻辑中调用依赖接口的方法 dep_->myFunction(); } private: IMyInterface* dep_; };
对应的测试代码应该是:
TEST(MyBusinessClassTest, triggersMyFunction) { MyClassMock mock(0,0,0); MyBusinessClass businessObj(&mock); // 设置预期:myFunction至少被调用一次 EXPECT_CALL(mock, myFunction()) .Times(AtLeast(1)); // 调用业务方法,间接触发Mock的myFunction businessObj.process(); }
这样测试就能验证你的业务逻辑是否正确调用了依赖接口的方法,这也是Mock的核心用途。
内容的提问来源于stack exchange,提问作者Simon Symon

