如何验证两个Mock方法被调用时传入的是同一引用?
验证两个Mock方法接收同一引用的Google Mock实现方案
嘿,这个场景我太熟悉了!用Google Mock验证两个Mock方法拿到的是同一个引用,核心就是抓住引用背后的对象地址——毕竟引用本质上就是绑定到同一个对象的“别名”,地址一致就代表是同一个引用。下面给你一步步拆解实现:
核心思路
我们需要先捕获第一个Mock方法(setupFoo)接收到的引用对应的对象地址,然后在第二个Mock方法(useFoo)的期望里,验证它接收的引用指向的对象地址和之前捕获的完全一致。
完整代码示例
假设我们的被测试逻辑、Mock类定义是这样的:
// 假设你的内部变量类型是Foo struct Foo { int value; }; // 负责填充Foo的Mock类 class MockFooSetup { public: MOCK_METHOD(void, setupFoo, (Foo& foo)); }; // 负责使用Foo的Mock类 class MockFooUser { public: MOCK_METHOD(void, useFoo, (const Foo& foo)); }; // 你要测试的方法 void testedMethod(MockFooSetup& setup, MockFooUser& user) { Foo stackVar; // 栈上的内部变量 setup.setupFoo(stackVar); // 引用传递给setupFoo user.useFoo(stackVar); // 同样的引用传递给useFoo }
对应的测试代码可以这么写:
#include <gmock/gmock.h> TEST(ReferenceTest, SameReferencePassedToBothMethods) { // 初始化Mock对象 MockFooSetup mockSetup; MockFooUser mockUser; // 声明一个指针,用来捕获setupFoo接收的对象地址 Foo* capturedFooPtr = nullptr; // 第一步:捕获setupFoo接收到的引用的对象地址 EXPECT_CALL(mockSetup, setupFoo(_)) .WillOnce(SaveArg<0>(&capturedFooPtr)); // 这里SaveArg<0>会把第一个参数(Foo&)对应的对象指针存到capturedFooPtr里 // 第二步:验证useFoo接收的是同一个对象的引用 EXPECT_CALL(mockUser, useFoo(testing::Ref(*capturedFooPtr))); // testing::Ref(x)会匹配任何指向x的引用,也就是参数的地址等于&x // 可选:如果担心调用顺序(比如useFoo先被调用导致capturedFooPtr为空),可以用InSequence强制顺序 // testing::InSequence seq; // 执行被测试方法 testedMethod(mockSetup, mockUser); }
关键细节解释
SaveArg<N>的作用:对于引用类型的参数,SaveArg<N>(&ptr)会把引用指向的对象的地址保存到指针ptr中——这正是我们判断是否为同一引用的核心依据。testing::Ref匹配器:这个匹配器会检查传入的参数是否是指定对象的引用(也就是参数的地址和指定对象的地址完全一致),完美契合我们的验证需求。- 强制调用顺序(可选):如果你的被测试逻辑有可能颠倒两个方法的调用顺序,加上
testing::InSequence可以确保setupFoo先被调用,避免capturedFooPtr为空导致的验证失败。
另一种灵活写法(用自定义匹配器)
如果你需要更灵活的验证逻辑,也可以用Truly匹配器结合lambda表达式来直接对比地址:
EXPECT_CALL(mockUser, useFoo(testing::Truly([capturedFooPtr](const Foo& foo) { return &foo == capturedFooPtr; })));
这种写法适合需要额外逻辑判断的场景,比如同时验证对象内容和地址的情况。
内容的提问来源于stack exchange,提问作者user3458
相关产品推荐
相关产品推荐

