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

为何GTest会生成Uninteresting mock function call警告?

问题

我给一个使用单例模式的类编写了GTest测试,该类通过调用公共成员实例的方法读取文件。我Mock了这个公共成员所属的类,并用ON_CALL手动填充JSON对象(而非从文件读取)。测试已通过,但输出中出现了Uninteresting mock function call警告,我无法理解该警告的产生原因,想知道是否可以忽略它,或是有解决该问题的方法。

完整代码

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <cstddef>
#include <filesystem>
#include <fstream>
#include <iostream>

#include "json.hpp"

using json = nlohmann::json;

class MockedUtil
{
    public:
    MockedUtil(){};
    ~MockedUtil(){};
    MOCK_METHOD(bool, readJSONFile, (const std::string &filePath, json &j));
    MOCK_METHOD(bool, writeJSONFile, (const std::string &filePath, const json &j));
};

template<typename T>
class Singleton
{
public:
  static T& get()
  {
    static T s(token{});

    // return the instance
    return s;
  }
  // copy constructor
  Singleton(const Singleton&) = delete;

  // assignment operator
  Singleton& operator=(const Singleton) = delete;

  // move constructor
  Singleton(const Singleton&&) = delete;

  // Move assign
  Singleton& operator=(const Singleton&&) = delete;

protected:
  // constructor
  Singleton();

  // destructor
  virtual ~Singleton();
  struct token
  {};
};

template<typename T>
Singleton<T>::Singleton()
{}

template<typename T>
Singleton<T>::~Singleton()
{}

class MyTest_mockfunctioncall_Test;
class ConcreteSingleton : public Singleton<ConcreteSingleton>
{
private:
  FRIEND_TEST(::MyTest, mockfunctioncall);
  std::string private_key;
  int val = -1;

public:
  ConcreteSingleton(token){};
  MockedUtil wrapper;
  bool readJSON(const std::string& settings, json& my_json)
  {
    this->private_key = "MyKey";
    const std::string path {"MyJson.json"};
    bool result =
        wrapper.readJSONFile(path, my_json);
    if (!result)
    {
        std::cout<<"Unable to read json file\n";
        return false;
    }
    if (!my_json[this->private_key].contains(settings))
    {
        std::cout<<"Setting is not present in my_json\n";
        std::cout<< my_json.dump(1, '\t') << "\n\n";
        return false;
    }
    my_json[settings] = my_json[this->private_key][settings];
    return true;
  }
};

class ClassToBeTested{
  public:
  ClassToBeTested() = default;
  int value;
  
  ~ClassToBeTested() = default;
  void foo()
  {
    value = -1;
    std::cout<<__FILE__<<":"<<__LINE__<<"; value: "<<value<<std::endl;
    json my_json = nullptr;
    std::cout<<" before calling\n";
    const std::string key {"my_key"};
    bool result = ConcreteSingleton::get().readJSON(key,my_json);
    if(result){
        value = my_json[key];
        std::cout<<"LINE COVERED\n";
    }
    else
    {
        std::cout<<"LINE NOT COVERED\n";
    }
    std::cout<<__FILE__<<":"<<__LINE__<<"; value: "<<value<<std::endl;
  }
};

TEST(MyTest, mockfunctioncall)
{
  auto& singleton = ConcreteSingleton::get();
  ClassToBeTested object;
  json my_json = nullptr;
  const std::string mystr{"MyJson"};
  ON_CALL(
    singleton.wrapper,
    readJSONFile(::testing::_, ::testing::_))
    .WillByDefault(
      [&](const std::string& filePath, json& j)
      {
        std::cout<<"inside lambda\n";
        j = R"( {"MyKey": {"my_key": 2}} )"_json;;
        return true;
      });
  
  object.foo();
  EXPECT_EQ(object.value, 2);
}

测试输出

test_file.cpp:105; value: -1
before calling
inside lambda
GMOCK WARNING:
Uninteresting mock function call - taking default action specified at:
test_file.cpp:128:
    Function call: readJSONFile(@0x7ffe1fea0ad0 "MyJson.json", @0x7ffe1fea0b60 null)
          Returns: true
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/main/docs/gmock_cook_book.md#knowing-when-to-expect-useoncall for details.
LINE COVERED
test_file.cpp:118; value: 2
分析与解决

警告原因

这个警告的核心是:你用ON_CALL为Mock方法设置了默认行为,但没有显式声明你期望该Mock方法被调用。GMock会将这种"有默认行为但未被预期的调用"判定为"无意义调用",即便你的测试逻辑正常执行,也会抛出该提示。

处理方案

你有两种可行的处理方式:

1. 直接忽略(确认调用符合预期时)

如果这个readJSONFile调用是你测试流程中明确需要的步骤,完全可以忽略该警告。GMock的提示也明确说明,只要调用是合理的,就无需处理。

2. 消除警告的具体方法

方法一:用EXPECT_CALL明确预期调用

将ON_CALL替换为EXPECT_CALL,明确告知GMock你期望该方法被调用的次数,同时保留原有行为逻辑:

EXPECT_CALL(singleton.wrapper, readJSONFile(::testing::_, ::testing::_))
    .Times(1)  // 明确预期调用1次
    .WillOnce(
      [&](const std::string& filePath, json& j)
      {
        std::cout<<"inside lambda\n";
        j = R"( {"MyKey": {"my_key": 2}} )"_json;;
        return true;
      });

如果不需要限制调用次数,可以用Times(::testing::AnyNumber())替代Times(1)。

方法二:使用NiceMock包装Mock类

NiceMock会自动屏蔽所有"无意义调用"的警告,适合只需要设置默认行为、不需要严格校验调用次数的场景。只需修改ConcreteSingleton中的成员定义:

// 原代码
MockedUtil wrapper;
// 修改为
::testing::NiceMock<MockedUtil> wrapper;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:47:03