如何在Google Test/Mock中从Mock方法正确调用被测类的方法
解决GMock中Mock方法先休眠再调用被测类方法的编译错误
嘿,刚接触GMock遇到这种问题很正常,我来帮你捋清楚问题出在哪以及怎么解决。
首先,你遇到的C2664编译错误,核心原因是**DoAll的每个参数都必须是GMock的Action类型**,但你直接写ClassUnderTest.MethodToCall()的时候,这是在构建EXPECT_CALL语句时就直接执行了这个方法,而不是把它包装成一个会在Mock方法被调用时才执行的Action,所以类型完全不匹配。
正确的实现方式
你的Wait Action定义是没问题的,只需要把调用被测类方法的操作改成GMock能识别的Action形式就行,这里有两种常用方案:
方案1:用Invoke配合Lambda(最灵活)
如果你的被测类实例是测试类的成员变量(比如classUnderTest),可以用Lambda表达式把调用逻辑包装起来,通过Invoke传递给DoAll:
// 假设classUnderTest是你的测试类的成员变量 EXPECT_CALL(mockedClass, mockedMethod()) .Times(1) .WillOnce(DoAll( Wait(100), // 先休眠100ms Invoke([this]() { this->classUnderTest.MethodToCall(); }) // 再调用被测类方法 ));
如果是全局的被测类实例,直接在Lambda里调用就行,不需要this。
方案2:自定义专门的Action
如果你需要多次调用被测类的这个方法,可以自定义一个带参数的Action来封装逻辑:
// 自定义Action:接收被测类实例指针,调用它的MethodToCall ACTION_P(CallCUTMethod, cut_ptr) { cut_ptr->MethodToCall(); } // 在测试中使用 EXPECT_CALL(mockedClass, mockedMethod()) .Times(1) .WillOnce(DoAll( Wait(100), CallCUTMethod(&classUnderTest) // 传入被测类实例指针 ));
关键要点提醒
- 永远记住:
EXPECT_CALL里的WillOnce/WillRepeatedly接收的是Action对象,不是直接执行的代码语句。直接写方法调用会在测试初始化阶段就执行,而不是Mock方法触发时执行。 - 确保你的被测类实例在Action执行时是有效的(比如不要用局部变量,最好是测试类的成员变量或者全局变量)。
内容的提问来源于stack exchange,提问作者Scott Madeux
相关产品推荐
相关产品推荐

