miniblink49 内置 Google Mock 速查手册:从 MOCK 宏到 Matcher 的 C++ 测试实战指南
【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核,用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49
Google Mock(gmock)是 Google 出品的 C++ mock 框架,用于为测试桩(stub)与模拟对象(mock object)快速生成可编程、可验证的替身,进而支撑单元测试中的交互式行为验证。本指南以 miniblink49 仓库中随 V8 6.7 一并内置的 Google Mock v1.5 CheatSheet 为骨架,逐条讲解 Mock 类定义、默认动作、期望设置、Matcher 与 Action 全量 API,并结合仓库源码揭示宏展开与底层实现原理。读完本文,你将能够在本仓库的v8_6_7/testing体系下独立编写、编译并运行基于 Google Mock 的 C++ 单元测试。
仓库中的 Google Mock:位置与组成
miniblink49 在v8_6_7/testing目录下完整内置了 Google Test/Google Mock 生态。Google Mock 本体位于 v8_6_7/testing/gmock,其中:
- 头文件集中在 v8_6_7/testing/gmock/include/gmock,入口为 gmock.h,它按顺序聚合了 actions、cardinalities、generated-actions、generated-function-mockers、generated-nice-strict、generated-matchers、matchers、more-actions、more-matchers 等全部子头文件(见 gmock.h 第 58-67 行);
- 实现代码位于 v8_6_7/testing/gmock/src(如
gmock-spec-builders.cc、gmock-matchers.cc、gmock-cardinalities.cc等); - 配套测试用例位于 v8_6_7/testing/gmock/test,包括
gmock-matchers_test.cc、gmock-actions_test.cc、gmock-spec-builders_test.cc、gmock-generated-function-mockers_test.cc、gmock-nice-strict_test.cc等,是阅读 API 行为的最佳活教材; - 辅助脚本位于 v8_6_7/testing/gmock/scripts,其中
generator/gmock_class.py可自动从接口头文件生成 mock 类,fuse_gmock_files.py可将 gmock 合并为单文件分发。
一、定义 Mock 类:MOCK_* 宏家族
1.1 Mock 一个普通类
假设被测代码依赖如下接口类:
class Foo { ... virtual ~Foo(); virtual int GetSize() const = 0; virtual string Describe(const char* name) = 0; virtual string Describe(int type) = 0; virtual bool Process(Bar elem, int count) = 0; };注意~Foo()必须声明为 virtual(否则多态析构与 mock 替换都会出问题)。其 mock 类这样定义:
#include <gmock/gmock.h> class MockFoo : public Foo { MOCK_CONST_METHOD0(GetSize, int()); MOCK_METHOD1(Describe, string(const char* name)); MOCK_METHOD1(Describe, string(int type)); MOCK_METHOD2(Process, bool(Bar elem, int count)); };宏命名规则为:MOCK_[CONST_]METHODn(方法名, 返回类型(形参列表)),其中n是参数个数,CONST对应被 mock 的 const 方法。从仓库的 gmock-generated-function-mockers.h 第 675-697 行 可以看到,MOCK_METHOD0~MOCK_METHOD10与MOCK_CONST_METHOD0~MOCK_CONST_METHOD10共 22 个宏被逐一展开定义,覆盖 0 到 10 个参数的所有组合。
若希望忽略所有"不关心的调用"(uninteresting calls),或把它们统统视为测试失败,可以使用:
NiceMock<MockFoo> nice_foo; // 类型是 MockFoo 的子类,忽略无关调用 StrictMock<MockFoo> strict_foo; // 类型是 MockFoo 的子类,把无关调用当作失败二者的实现位于 gmock-generated-nice-strict.h:NiceMock定义在第 80 行,StrictMock定义在第 272 行,此外还有一个"中间档"NaggyMock(第 176 行)——它会打印无关调用的警告但不失败。默认(裸MockFoo)行为即 Naggy:记录警告、执行默认动作。
1.2 Mock 一个类模板
对类模板,只需在宏名后面追加_T:
template <typename Elem> class StackInterface { public: ... virtual ~StackInterface(); virtual int GetSize() const = 0; virtual void Push(const Elem& x) = 0; }; template <typename Elem> class MockStack : public StackInterface<Elem> { public: ... MOCK_CONST_METHOD0_T(GetSize, int()); MOCK_METHOD1_T(Push, void(const Elem& x)); };同样注意~StackInterface()必须为 virtual。仓库中MOCK_METHOD0_T~MOCK_METHOD10_T、MOCK_CONST_METHOD0_T~MOCK_CONST_METHOD10_T定义在 gmock-generated-function-mockers.h 第 699-731 行。
1.3 指定调用约定(Calling Convention)
如果 mock 函数不使用默认调用约定,可在宏名后追加_WITH_CALLTYPE,并把调用约定作为宏的第一个参数传入:
MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n)); MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y));其中STDMETHODCALLTYPE由 Windows 的<objbase.h>定义。该系列宏同样覆盖 0~10 参数、const/non-const 以及_T模板变体,见 gmock-generated-function-mockers.h 第 734 行起。
1.4 源码视角:MOCK 宏到底生成了什么
以MOCK_METHOD1为例,其展开逻辑位于 gmock-generated-function-mockers.h 第 375-391 行:它实际上生成了三样东西——
- 一个真正的成员函数
Method(gmock_a1),内部通过FunctionMocker<...>::Invoke(gmock_a1)把调用转发给 mock 调度器; - 一个
gmock_##Method(matcher)接口,用于EXPECT_CALL/ON_CALL内部把 matcher 注册到当前MockSpec; - 一个
mutable FunctionMocker<...>成员变量,负责记录调用次数、匹配实参并执行 action。
FunctionMocker<R(A1)>的完整实现见 gmock-generated-function-mockers.h 第 84-103 行:With()通过SetMatchers登记 matcher,Invoke()通过InvokeWith(ArgumentTuple(a1))触发匹配与动作执行。理解这一展开关系,就理解了为什么 mock 方法与原方法签名必须一一对应。
二、在测试中使用 Mock:六步标准流程
官方推荐的典型流程是:
- 导入命名空间:除宏外,所有 Google Mock 名字都在
testing命名空间下,用using ::testing::...;按需引入; - 创建 mock 对象;
- (可选)设置默认动作;
- 设置期望:规定"会被怎么调用、调用时做什么";
- 运行被测代码,必要时用 Google Test 的断言检查结果;
- 析构时自动验证:mock 对象析构时,Google Mock 会自动检查其上的所有期望是否已被满足。
完整示例:
using ::testing::Return; // #1 TEST(BarTest, DoesThis) { MockFoo foo; // #2 ON_CALL(foo, GetSize()) // #3 .WillByDefault(Return(1)); // ... 其他默认动作 ... EXPECT_CALL(foo, Describe(5)) // #4 .Times(3) .WillRepeatedly(Return("Category 5")); // ... 其他期望 ... EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 } // #6 析构时自动验证第 6 步的"自动验证"由gmock-spec-builders.cc中的FunctionMockerBase析构逻辑实现,这也是 Google Mock 相比手写桩代码的核心价值:期望不会被悄悄遗忘。
三、设置默认动作(Default Actions)
对于返回void、bool、数值或指针类型的函数,Google Mock 内置了默认动作(通常返回"零值"),无需任何配置。
全局定制某返回类型T的默认值:
using ::testing::DefaultValue; DefaultValue<T>::Set(value); // 设置全局默认返回值 // ... 使用 mocks ... DefaultValue<T>::Clear(); // 清除全局默认值针对特定方法定制,使用ON_CALL():
ON_CALL(mock_object, method(matchers)) .With(multi_argument_matcher) // 可选 .WillByDefault(action);ON_CALL只设定"默认行为",不产生任何"必须调用"的约束——方法与EXPECT_CALL相同,但语义完全不同。
四、设置期望:EXPECT_CALL 全解
EXPECT_CALL()为 mock 方法设置期望(会被调用几次、如何匹配实参、每次做什么),其完整语法链为:
EXPECT_CALL(mock_object, method(matchers)) .With(multi_argument_matcher) ? // 可选 .Times(cardinality) ? // 可选 .InSequence(sequences) * // 可多个 .After(expectations) * // 可多个 .WillOnce(action) * // 可多个 .WillRepeatedly(action) ? // 可选 .RetiresOnSaturation(); ? // 可选(?表示最多一次,*表示可多次。)
省略Times()时的默认调用次数规则:
- 既无
WillOnce()也无WillRepeatedly()→ 默认Times(1); - 有
n个WillOnce()但无WillRepeatedly()→ 默认Times(n)(n >= 1); - 有
n个WillOnce()且有WillRepeatedly()→ 默认Times(AtLeast(n))(n >= 0)。
没有任何EXPECT_CALL()的方法可以任意次数被调用,每次调用都走默认动作。这条语义是区分ON_CALL与EXPECT_CALL的关键:前者零约束,后者至少一次。
五、Matcher:参数匹配器大全
Matcher匹配单个参数,可出现在ON_CALL()/EXPECT_CALL()内部,也可直接用于校验某个值:
| 宏 | 说明 |
|---|---|
EXPECT_THAT(value, matcher) | 断言value匹配matcher,失败为非致命 |
ASSERT_THAT(value, matcher) | 同EXPECT_THAT,但失败为致命错误 |
5.1 通配符
| Matcher | 含义 |
|---|---|
_ | 实参可以是正确类型的任意值 |
A<type>()或An<type>() | 实参可以是type类型的任意值 |
5.2 泛型比较
| Matcher | 含义 |
|---|---|
Eq(value)或直接写value | argument == value |
Ge(value) | argument >= value |
Gt(value) | argument > value |
Le(value) | argument <= value |
Lt(value) | argument < value |
Ne(value) | argument != value |
IsNull() | 实参是NULL指针(裸指针或智能指针) |
NotNull() | 实参是非空指针(裸指针或智能指针) |
Ref(variable) | 实参是variable的引用 |
TypedEq<type>(value) | 实参类型为type且等于value;当 mock 函数重载时,可能需要用它替代Eq(value) |
除Ref()外,这些 matcher 会拷贝value(防止其后续被修改或析构)。若编译器提示value没有公开拷贝构造函数,可用ByRef()包裹,例如Eq(ByRef(non_copyable_value))——但请确保non_copyable_value之后不再变化,否则 matcher 语义会被改变。
5.3 浮点 Matcher
| Matcher | 含义 |
|---|---|
DoubleEq(a_double) | 实参为double,与a_double近似相等,两个 NaN 视为不相等 |
FloatEq(a_float) | 实参为float,与a_float近似相等,两个 NaN 视为不相等 |
NanSensitiveDoubleEq(a_double) | 同DoubleEq,但两个 NaN 视为相等 |
NanSensitiveFloatEq(a_float) | 同FloatEq,但两个 NaN 视为相等 |
以上 matcher 采用基于 ULP(unit in the last place)的比较,与 Google Test 一致,会自动依据期望值的绝对值选取合理的误差界。DoubleEq()/FloatEq()遵循 IEEE 标准(两个 NaN 比较相等返回 false);NanSensitive*变体则把两个 NaN 视为相等,通常更符合实际诉求。相关实现与测试可参见 gmock-matchers.cc 与 gmock-matchers_test.cc。
5.4 字符串 Matcher
实参可以是 C 字符串或 C++ string 对象:
| Matcher | 含义 |
|---|---|
ContainsRegex(string) | 实参匹配给定正则表达式 |
EndsWith(suffix) | 实参以suffix结尾 |
HasSubstr(string) | 实参包含子串string |
MatchesRegex(string) | 实参整体匹配正则(首字符开始、末字符结束) |
StartsWith(prefix) | 实参以prefix开头 |
StrCaseEq(string) | 实参与string相等(忽略大小写) |
StrCaseNe(string) | 实参与string不相等(忽略大小写) |
StrEq(string) | 实参与string相等 |
StrNe(string) | 实参与string不相等 |
StrCaseEq()、StrCaseNe()、StrEq()、StrNe()同样适用于宽字符串。
5.5 容器 Matcher
大多数 STL 容器支持==,因此可直接用Eq(expected_container)或直接传入容器精确匹配。需要内联书写元素、更灵活匹配或更友好的失败信息时,使用:
| Matcher | 含义 |
|---|---|
Contains(e) | 容器包含一个匹配e的元素,e可以是值或 matcher |
ElementsAre(e0, e1, ..., en) | 容器恰有n + 1个元素,第 i 个元素匹配ei(值或 matcher),支持 0 到 10 个参数 |
ElementsAreArray(array)或ElementsAreArray(array, count) | 同ElementsAre(),但期望值来自 C 风格数组 |
ContainerEq(container) | 同Eq(container),但失败信息会指出哪些元素只在其中一个容器中出现 |
这些 matcher 还能匹配两类数组形态:①按引用传递的原生数组(如Foo(const int (&a)[5]));②指针 + 长度的组合(如Bar(const T* buffer, int len),见下文"多参数 Matcher")。数组可以是多维的。
5.6 成员 Matcher
| Matcher | 含义 |
|---|---|
Field(&class::field, m) | 实参对象的field成员(实参为裸指针时写作argument->field)匹配 matcherm |
Key(e) | argument.first匹配e(值或 matcher),例如Contains(Key(Le(5)))可验证 map 中存在<= 5的键 |
Pair(m1, m2) | 实参为std::pair,first匹配m1且second匹配m2 |
Property(&class::property, m) | 实参对象的property()访问器返回值(裸指针时为argument->property())匹配 matcherm |
5.7 匹配函数/仿函数结果
| Matcher | 含义 |
|---|---|
ResultOf(f, m) | f(argument)匹配 matcherm,其中f为函数或仿函数 |
5.8 指针 Matcher
| Matcher | 含义 |
|---|---|
Pointee(m) | 实参(智能指针或裸指针)所指向的值匹配 matcherm |
5.9 多参数 Matcher(用于.With())
针对两个参数x和y,可在.With()中使用Eq()、Ge()、Gt()、Le()、Lt()、Ne(),分别对应x == y、x >= y、x > y、x <= y、x < y、x != y。
以下选择器可从实参元组中选取子集(或重新排序)参与匹配:
| Matcher | 含义 |
|---|---|
AllArgs(m) | 等价于m,在.With(AllArgs(m))中是语法糖 |
Args<N1, N2, ..., Nk>(m) | 被选中的(0 基索引)k 个实参匹配m,例如Args<1, 2>(Contains(5)) |
5.10 组合 Matcher
| Matcher | 含义 |
|---|---|
AllOf(m1, m2, ..., mn) | 实参匹配所有 matcherm1~mn(逻辑与) |
AnyOf(m1, m2, ..., mn) | 实参至少匹配其中一个(逻辑或) |
Not(m) | 实参不匹配 matcherm(逻辑非) |
5.11 Matcher 适配器
| Matcher | 含义 |
|---|---|
MatcherCast<T>(m) | 将 matcherm转换为Matcher<T>类型 |
SafeMatcherCast<T>(m) | 安全转换 matcherm为Matcher<T>(细节见 v1.5 CookBook 的 Casting Matchers 章节) |
Truly(predicate) | predicate(argument)在 C++ 语义下为真,predicate为函数或仿函数 |
5.12 把 Matcher 当谓词用
| Matcher | 含义 |
|---|---|
Matches(m) | 一元仿函数,实参匹配m时返回true |
ExplainMatchResult(m, value, result_listener) | 若value匹配m返回true,并把匹配/不匹配原因写入result_listener |
Value(x, m) | x的值匹配m时返回true |
5.13 自定义 Matcher
MATCHER(IsEven, "") { return (arg % 2) == 0; } MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; } MATCHER_P2(IsBetween, a, b, "is between %(a)s and %(b)s") { return a <= arg && arg <= b; }注意三点:①MATCHER*宏不能定义在函数或类内部;② matcher 函数体必须纯函数式(无副作用,结果只依赖被匹配值与 matcher 参数);③ 可用PrintToString(x)把任意类型的值转成字符串用于诊断输出。
5.14 Matcher 用作测试断言
| 宏 | 说明 |
|---|---|
ASSERT_THAT(expression, m) | 若表达式值不匹配m,产生致命失败 |
EXPECT_THAT(expression, m) | 若表达式值不匹配m,产生非致命失败 |
六、Action:定义 mock 函数被调用时的行为
Action规定 mock 函数被调用时应执行什么。
6.1 返回值
| Action | 含义 |
|---|---|
Return() | 从voidmock 函数返回 |
Return(value) | 返回value |
ReturnArg<N>() | 返回第N(0 基)个实参 |
ReturnNew<T>(a1, ..., ak) | 返回new T(a1, ..., ak),每次调用创建新对象 |
ReturnNull() | 返回空指针 |
ReturnRef(variable) | 返回variable的引用 |
6.2 副作用
| Action | 含义 |
|---|---|
Assign(&variable, value) | 把value赋给variable |
DeleteArg<N>() | 删除第N(0 基)个实参(必须是指针) |
SaveArg<N>(pointer) | 把第N(0 基)个实参保存到*pointer |
SetArgReferee<N>(value) | 把value赋给第N(0 基)个实参引用的变量 |
SetArgumentPointee<N>(value) | 把value赋给第N(0 基)个实参指向的变量 |
SetArrayArgument<N>(first, last) | 把源区间 [first,last) 的元素拷贝到第N(0 基)个实参指向的数组(指针或迭代器),不接管源元素所有权 |
SetErrnoAndReturn(error, value) | 设置errno为error并返回value |
Throw(exception) | 抛出给定异常(任意可拷贝值),自 v1.1.0 可用 |
6.3 调用函数/仿函数
| Action | 含义 |
|---|---|
Invoke(f) | 以传给 mock 函数的实参调用f(全局/静态函数或仿函数) |
Invoke(object_pointer, &class::method) | 以传给 mock 函数的实参调用对象上的方法 |
InvokeWithoutArgs(f) | 调用无参的f(全局/静态函数或仿函数) |
InvokeWithoutArgs(object_pointer, &class::method) | 调用对象上无参的方法 |
InvokeArgument<N>(arg1, arg2, ..., argk) | 以k个参数调用 mock 函数的第N(0 基)个实参(必须是函数或仿函数) |
被调用函数的返回值即 action 的返回值。定义供Invoke*()使用的函数时,未用到的参数可声明为Unused:
double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } ... EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance));在InvokeArgument<N>(...)中,若某实参需按引用传递,用ByRef()包裹:
InvokeArgument<2>(5, string("Hi"), ByRef(foo))上式会调用 mock 函数第 2 号实参,向其传入5与string("Hi")(按值)以及foo(按引用)。
6.4 默认 Action
| Action | 含义 |
|---|---|
DoDefault() | 执行默认动作(ON_CALL()指定的或内置的) |
注意:由于技术原因,DoDefault()不能用于组合 action 内部,否则会在运行时出错。
6.5 组合 Action
| Action | 含义 |
|---|---|
DoAll(a1, a2, ..., an) | 每次调用依次执行a1~an,返回an的结果;前n - 1个子 action 必须返回 void |
IgnoreResult(a) | 执行 actiona并忽略其返回值(a不能返回 void) |
WithArg<N>(a) | 把 mock 函数第N(0 基)个实参传给 actiona执行 |
WithArgs<N1, N2, ..., Nk>(a) | 把选中的(0 基)实参传给 actiona执行 |
WithoutArgs(a) | 不带任何参数执行 actiona |
6.6 自定义 Action
ACTION(Sum) { return arg0 + arg1; } ACTION_P(Plus, n) { return arg0 + n; } ACTION_Pk(Foo, p1, ..., pk) { statements; }ACTION_Pk是通用形式:定义一个带k个参数的自定义 action。ACTION*宏不能用在函数或类内部。
七、Cardinality:调用次数约束
以下值用于Times()指定 mock 函数应被调用的次数:
| Cardinality | 含义 |
|---|---|
AnyNumber() | 可被调用任意次 |
AtLeast(n) | 至少调用n次 |
AtMost(n) | 至多调用n次 |
Between(m, n) | 调用次数在m到n(含)之间 |
Exactly(n)或直接写n | 恰好调用n次;n为 0 时表示绝不能被调用 |
八、期望顺序控制
默认情况下,期望可以任意顺序被匹配。若要求全部或部分期望按指定顺序匹配,有两种方式,可独立或组合使用。
8.1 After 子句
using ::testing::Expectation; ... Expectation init_x = EXPECT_CALL(foo, InitX()); Expectation init_y = EXPECT_CALL(foo, InitY()); EXPECT_CALL(foo, Bar()) .After(init_x, init_y);表示Bar()只能在InitX()和InitY()都已被调用之后调用。若编写时不确定前置期望的数量,可用ExpectationSet收集:
using ::testing::ExpectationSet; ... ExpectationSet all_inits; for (int i = 0; i < element_count; i++) { all_inits += EXPECT_CALL(foo, InitElement(i)); } EXPECT_CALL(foo, Bar()) .After(all_inits);表示Bar()必须在所有元素初始化完成后才能调用(元素之间的先后无关)。在.After()中使用后再修改ExpectationSet不会影响.After()的语义。
8.2 Sequence(序列)
当有一长串顺序期望时,用sequence更简洁——无需为链上每个期望单独命名。同一序列中的所有期望调用必须按声明顺序发生:
using ::testing::Sequence; Sequence s1, s2; ... EXPECT_CALL(foo, Reset()) .InSequence(s1, s2) .WillOnce(Return(true)); EXPECT_CALL(foo, GetSize()) .InSequence(s1) .WillOnce(Return(1)); EXPECT_CALL(foo, Describe(A<const char*>())) .InSequence(s2) .WillOnce(Return("dummy"));表示Reset()必须同时先于GetSize()和Describe(),而后两者可任意先后。
批量放入序列的便捷写法:
using ::testing::InSequence; { InSequence dummy; EXPECT_CALL(...)...; EXPECT_CALL(...)...; ... EXPECT_CALL(...)...; }表示dummy作用域内的所有期望调用必须严格按顺序发生(变量名dummy本身无关紧要)。
九、验证与重置 Mock
Google Mock 会在 mock 对象析构时自动验证期望,也可提前手动验证:
using ::testing::Mock; ... // 验证并移除 mock_obj 上的期望;成功返回 true Mock::VerifyAndClearExpectations(&mock_obj); ... // 验证并移除期望;同时移除 ON_CALL() 设置的默认动作;成功返回 true Mock::VerifyAndClear(&mock_obj);还可以声明某 mock 对象允许泄漏、无需验证:
Mock::AllowLeak(&mock_obj);十、便捷 Mock 类:MockFunction
Google Mock 提供便捷的 mock 类模板,用于直接 mock 任意签名的函数:
class MockFunction<R(A1, ..., An)> { public: MOCK_METHODn(Call, R(A1, ..., An)); };其典型应用(如把"回调被调用"作为检查点)可参考 v1.5 CookBook 的 Using Check Points 章节。
十一、命令行 Flags
| Flag | 说明 |
|---|---|
--gmock_catch_leaked_mocks=0 | 不把泄漏的 mock 对象报告为失败 |
--gmock_verbose=LEVEL | 设置 Google Mock 消息的默认详细级别(info、warning或error) |
十二、如何在 miniblink49 仓库中使用
Google Mock 已完整内置,无需联网下载。实践路径:
- 阅读入门文档:从 v1.5 ForDummies 入手,再对照本文速查表;
- 查看测试范例:仓库自带大量可编译用例,如 gmock-matchers_test.cc、gmock-actions_test.cc、gmock-spec-builders_test.cc、gmock-nice-strict_test.cc,直接以这些文件为模板编写自己的测试;
- 自动化生成 mock:对大型接口,可用 scripts/generator/gmock_class.py 从类头文件自动生成
Mock*类骨架,再手工按本文规则补全宏;scripts/fuse_gmock_files.py可把 gmock 合并为便于分发的单头文件; - 编译与运行:将 v8_6_7/testing/gmock 加入头文件搜索路径,链接
src/下的gmock-all.cc(或gmock.cc+gmock_main.cc以启用 gtest_main 入口),通过 Makefile 或 CMake(CMakeLists.txt)即可构建;调试匹配失败时可搭配--gmock_verbose=info打开详细输出。
实战要点回顾:Mock 类定义遵循"接口虚析构 +MOCK_[CONST_]METHODn[_T][_WITH_CALLTYPE]"模板;测试组织遵循"建对象 → 设默认 → 定期望 → 跑代码 → 析构验证"六步法;Matcher 管"怎么匹配",Action 管"做什么",Cardinality 管"调用几次",After/InSequence管"顺序如何"——把这张速查表用熟,就掌握了 Google Mock 的全部核心 API。
【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核,用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考