Google Test中,参数与EXPECT_CALL超出作用域后匹配是否合法?
针对你提出的核心问题,逐一解答如下:
1. 局部obj超出作用域后,后续匹配操作是否可行?
可行。因为你的handle方法参数是值传递(void(Object obj)),当你在EXPECT_CALL中写handle(obj)时,Google Mock会拷贝当前obj的完整值,并将这个副本存储到内部的期望调用记录中。即使原来的局部obj离开作用域被销毁,Google Mock保存的副本依然存在,后续调用handle时会用这个副本做匹配对比。
如果handle是引用传递(void(Object& obj)),直接写handle(obj)会导致匹配器持有局部obj的引用,此时obj销毁后匹配会出现未定义行为,但你的示例是值传递,所以不存在这个问题。
2. EXPECT_CALL是否会创建局部变量?
EXPECT_CALL本身不会在你的代码块中创建新的局部变量,但它会在Google Mock的内部运行时结构中,创建存储期望调用信息的对象(包括刚才提到的参数副本)。这些内部对象的生命周期会覆盖整个测试用例的执行过程,直到测试结束才会被清理。
3. 示例中的测试代码是否合法?
合法,只要你的Object类型满足可拷贝构造的要求(因为Google Mock需要拷贝参数值)。如果Object禁用了拷贝(比如删除了拷贝构造函数),这段代码会编译失败,此时你需要改用引用匹配(比如handle(Ref(obj)),但要确保obj在调用期间存活)或者其他自定义匹配器。
另外需要注意:示例中三次EXPECT_CALL默认会要求handle按照顺序被调用三次,每次匹配对应的obj副本值,如果你后续的三次handle调用传入的对象值和之前三个obj的拷贝值一致,测试就会通过。
内容的提问来源于stack exchange,提问作者fluter

