You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GMock使用问题:TIMES报错、Mock行为修改及测试失败排查

一、基础Mock场景问题

待Mock的基类与Mock类定义

基类代码:

class Base{
public:
void virtual func() { sleep(3); }
};

Mock类代码:

class Mock: public Base{
public:
MOCK_METHOD(void, func, (), (override));
};

测试用例代码:

TEST(TestMockSanity, AbleToMock) {                                                        
Mock mock;                                                                    
EXPECT_CALL(mock, func());   
}                                                        

问题1:语法错误:class testing::internal::TypedExpectation<void()> has no member named ‘TIMES’

解决方法:

  • TIMES是GMock的约束宏,需通过testing::Times()方式调用,正确链式写法示例:
    EXPECT_CALL(mock, func()).Times(testing::AtLeast(1));
    
  • 注意:必须使用testing::命名空间下首字母大写的Times,而非全大写的TIMES,否则会触发语法错误。

问题2:如何将Mock类中func的实现改为sleep(0)?

推荐解决方法:使用ON_CALL设置默认行为,既保留Mock的验证能力,又自定义实现:

TEST(TestMockSanity, AbleToMock) {
    Mock mock;
    ON_CALL(mock, func()).WillByDefault([](){ sleep(0); });
    // 若需验证调用,可保留EXPECT_CALL
    EXPECT_CALL(mock, func());
    mock.func();
}

也可在Mock类中直接重写,但会失去Mock的灵活性,仅适合固定默认场景:

class Mock: public Base{
public:
    MOCK_METHOD(void, func, (), (override));
    void func() override {
        sleep(0);
    }
};

二、Mock测试失败问题

相关代码文件

./real.hpp

class Real {
 public:
  Real(){};
  virtual ~Real(){};
  virtual int run();
  virtual int dont_run();
};

./real.cpp

#include "real.hpp"

int Real::run() { return 0; };
int Real::dont_run() { return 1; };

./meson.build

project(
  'gtest',
  'cpp',
  default_options : [
    'cpp_std=c++14',
  ],
)

sources = files('main.cpp', 'real.cpp')

executable(
  'real',
  sources,
  install : false,
)

executable(
  'mock',
  files('real.cpp', 'mock.cpp'),
  dependencies: [dependency('gtest'), dependency('gmock')],
  install : false,
)

./mock.cpp

#include "gmock/gmock.h"  // MOCK_METHOD
#include "gtest/gtest.h"  // TEST
#include "real.hpp"

class MockReal : public Real {
 public:
  MOCK_METHOD(int, run, (), (override));
  MOCK_METHOD(int, dont_run, (), (override));

  void delegate(){
      ON_CALL(*this, run).WillByDefault([this](){
          return 1;
      });
      ON_CALL(*this, dont_run).WillByDefault([this](){
          return 2;
      });
  }
};

TEST(TestMockSanity, AbleToMock) {
  MockReal mock;

  EXPECT_EQ(0, mock.run());
  EXPECT_EQ(1, mock.dont_run());

  mock.delegate();

  EXPECT_EQ(1, mock.run());
  EXPECT_EQ(2, mock.dont_run());
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

测试运行结果

[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from TestMockSanity
[ RUN      ] TestMockSanity.AbleToMock

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: run()
          Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: dont_run()
          Returns: 0
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.
../mock.cpp:24: Failure
Expected equality of these values:
  1
  mock.dont_run()
    Which is: 0

GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
../mock.cpp:11:
    Function call: run()
          Returns: 1
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.

GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
../mock.cpp:14:
    Function call: dont_run()
          Returns: 2
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#knowing-when-to-expect for details.
[  FAILED  ] TestMockSanity.AbleToMock (0 ms)
[----------] 1 test from TestMockSanity (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] TestMockSanity.AbleToMock

 1 FAILED TEST

问题原因与解决方法

核心问题分析

  1. Mock默认行为未调用基类方法:GMock覆盖基类虚函数后,默认返回类型的默认值(int类型返回0),而非调用基类dont_run()的返回值1,导致断言失败。
  2. 构建配置符号冲突:meson.build中mock可执行文件同时链接real.cpp和mock.cpp,真实实现与Mock方法符号冲突,导致Mock机制无法正常工作。

解决步骤

  1. 修改Mock类,默认调用基类实现:
    在Mock类构造函数中设置默认行为为调用基类方法,满足测试预期:

    class MockReal : public Real {
     public:
      MOCK_METHOD(int, run, (), (override));
      MOCK_METHOD(int, dont_run, (), (override));
    
      MockReal() {
          // 默认调用基类方法
          ON_CALL(*this, run).WillByDefault([this](){ return Real::run(); });
          ON_CALL(*this, dont_run).WillByDefault([this](){ return Real::dont_run(); });
      }
    
      void delegate(){
          ON_CALL(*this, run).WillByDefault([this](){
              return 1;
          });
          ON_CALL(*this, dont_run).WillByDefault([this](){
              return 2;
          });
      }
    };
    
  2. 修改meson.build,消除符号冲突:
    编译测试程序时无需链接real.cpp,Mock类已继承Real的声明,调用基类实现可直接通过Real::method()完成:

    executable(
      'mock',
      files('mock.cpp'),
      dependencies: [dependency('gtest'), dependency('gmock')],
      install : false,
    )
    
  3. 验证结果:
    修改后,测试用例中:

    • 调用delegate()前,mock.run()返回基类的0,mock.dont_run()返回基类的1
    • 调用delegate()后,run()返回1,dont_run()返回2
      所有断言将通过,GMOCK的"Uninteresting mock function call"警告也会消失。

内容的提问来源于stack exchange,提问作者CIsForCookies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:30:47