0Pricing
C++ Academy · 课时

使用 GMock 模拟

模拟依赖项

使用 GMock 模拟 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

为什么使用 Mock

GMock 会创建能够记录调用并返回预先设定结果的虚假对象。Mock 可以将被测试单元与数据库或网络等速度较慢或不可预测的依赖项隔离开来。

从接口开始

可进行 Mock 的依赖项通常是包含虚方法的抽象基类。

#include <string>

class Database {
public:
    virtual ~Database() = default;
    virtual std::string get(int id) = 0;
    virtual bool save(const std::string& v) = 0;
};

定义 Mock 类

使用 MOCK_METHOD 为每个虚方法生成 Mock,并指定返回类型、名称、参数和限定符。

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

class Database {
public:
    virtual ~Database() = default;
    virtual std::string get(int id) = 0;
};

class MockDatabase : public Database {
public:
    MOCK_METHOD(std::string, get, (int id), (override));
};

设置预期

EXPECT_CALL 声明 Mock 方法应如何被调用以及返回什么。WillOnce(Return(...)) 会预先设定返回结果。

#include <gmock/gmock.h>
using ::testing::Return;

TEST(DbTest, ReturnsValue) {
    MockDatabase db;
    EXPECT_CALL(db, get(1)).WillOnce(Return("alice"));
    EXPECT_EQ(db.get(1), "alice");
}

参数匹配器

预期可以使用匹配器宽松地匹配参数,例如 _(任意值)、Gt(5) 或 HasSubstr("x")。

#include <gmock/gmock.h>
using ::testing::_;
using ::testing::Return;

TEST(DbTest, AnyId) {
    MockDatabase db;
    EXPECT_CALL(db, get(_)).WillRepeatedly(Return("x"));
    EXPECT_EQ(db.get(99), "x");
}

调用次数

使用 Times 指定一次调用应当发生多少次。

  • Times(1) 恰好调用一次
  • Times(AtLeast(2))
  • Times(0) 不得调用
#include <gmock/gmock.h>
using ::testing::AtLeast;
using ::testing::Return;

TEST(DbTest, CalledTwice) {
    MockDatabase db;
    EXPECT_CALL(db, get(1)).Times(AtLeast(2)).WillRepeatedly(Return("v"));
    db.get(1);
    db.get(1);
}

返回操作

操作决定行为。

  • Return(value)
  • ReturnRef(ref)
  • Throw(exception)
  • Invoke(callable) 用于运行自定义代码

注入模拟对象

被测单元必须通过指向接口的指针或接口引用来接收依赖项。这就是依赖注入,也是模拟成为可能的原因。

#include <string>

class Database;

class UserService {
    Database& db;
public:
    UserService(Database& d) : db(d) {}
    std::string name(int id);
};

验证交互

模拟对象销毁时,GMock 会验证所有 EXPECT_CALL 预期。未满足的预期(调用次数错误或缺少调用)会自动导致测试失败。

友好、严格和唠叨型模拟对象

控制如何处理意外调用。

  • NiceMock:忽略无关紧要的调用
  • StrictMock:任何意外调用都会导致失败
  • 默认(唠叨型):对无关紧要的调用发出警告

只模拟自己拥有的内容

优先模拟您自己的接口,而不是第三方具体类。为外部库引入一层精简的包装接口,让测试保持稳定。

快速检查

回忆 GMock 何时检查预期。

回顾

您学会了 GMock。

  • 使用 MOCK_METHOD 模拟虚接口
  • EXPECT_CALL 加上操作即可编排行为
  • 匹配器和 Times 控制参数与调用次数
  • 注入模拟对象;预期会在销毁时得到验证

常见问题解答

「使用 GMock 模拟」课时是免费的吗?

是的 — 「使用 GMock 模拟」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「使用 GMock 模拟」这节课中我会学到什么?

模拟依赖项 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用 GMock 模拟」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 设置 GTest
  2. 断言与匹配器
  3. 测试夹具与设置
  4. 使用 GMock 模拟
← 返回 C++ Academy