GoogleTest 匹配器(Matchers)完全指南:从基础到高级用法

GoogleTest 匹配器(Matchers)完全指南:从基础到高级用法

【免费下载链接】googletest 由 Google 开发的一款用于 C++ 的单元测试和模拟(mocking)框架 【免费下载链接】googletest 项目地址: https://gitcode.com/GitHub_Trending/go/googletest

什么是 GoogleTest 匹配器

GoogleTest 匹配器(Matchers)是 GoogleTest 测试框架中用于验证值的强大工具。它们提供了一种声明式的方式来描述我们期望的值应该满足什么条件,相比传统的 ASSERT/EXPECT 断言,匹配器提供了更丰富的表达能力和更清晰的错误信息。

基本使用方式

使用匹配器主要有两种方式:

  1. 在测试断言中直接使用:
EXPECT_THAT(actual_value, matcher);
ASSERT_THAT(actual_value, matcher);
  1. 在模拟对象(Mock)的期望设置中使用:
EXPECT_CALL(mock_object, method(matchers));

EXPECT_THATASSERT_THAT 的区别在于前者生成非致命失败,后者生成致命失败。

匹配器分类详解

1. 通配符匹配器

  • _ : 匹配任何类型的任何值
  • A<type>() / An<type>() : 匹配指定类型的任何值

这些匹配器在你不关心具体值但需要确保类型正确时非常有用。

2. 通用比较匹配器

匹配器等价比较说明
Eq(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()-检查指针是否非 NULL

重要提示:这些匹配器会复制传入的值,如果值不可复制,可以使用 std::ref 包装。

3. 浮点数匹配器

由于浮点数比较的特殊性,GoogleTest 提供了专门的浮点数匹配器:

  • DoubleEq/FloatEq : 近似相等比较,将 NaN 视为不等
  • NanSensitiveDoubleEq/NanSensitiveFloatEq : 近似相等比较,将 NaN 视为相等
  • DoubleNear/FloatNear : 允许指定最大绝对误差的范围比较

这些匹配器使用 ULP(Unit in the Last Place)比较算法,能智能地根据期望值的大小选择合适的误差范围。

4. 字符串匹配器

支持对 C 字符串和 C++ string 对象的丰富匹配:

  • StrEq/StrNe : 字符串完全相等/不等比较
  • StrCaseEq/StrCaseNe : 忽略大小写的字符串比较
  • ContainsRegex/MatchesRegex : 正则表达式匹配
  • HasSubstr : 包含子字符串
  • StartsWith/EndsWith : 检查开头/结尾

5. 容器匹配器

对 STL 容器提供了丰富的匹配能力:

  • ContainerEq : 严格容器相等比较,并提供详细的差异信息
  • ElementsAre : 按顺序匹配每个元素
  • UnorderedElementsAre : 不按顺序匹配所有元素
  • Contains : 检查是否包含特定元素
  • Each : 检查所有元素都满足条件
  • IsSubsetOf/IsSupersetOf : 子集/超集检查
  • WhenSorted : 排序后检查

示例

std::vector<int> v = {1, 2, 3};
EXPECT_THAT(v, ElementsAre(1, 2, 3));
EXPECT_THAT(v, UnorderedElementsAre(3, 2, 1));
EXPECT_THAT(v, Contains(2));

6. 成员匹配器

用于检查对象成员或属性:

  • Field : 匹配对象的数据成员
  • Property : 匹配对象的属性(getter方法返回值)
  • Key : 匹配 map 的键
  • Pair : 匹配 pair 的两个元素
  • FieldsAre : 同时匹配多个字段(支持结构化绑定)

示例

struct Person {
  std::string name;
  int age;
};

Person p{"Alice", 30};
EXPECT_THAT(p, Field(&Person::name, "Alice"));
EXPECT_THAT(p, FieldsAre("Alice", 30));

7. 高级匹配器

  • ResultOf : 对值应用函数后再匹配
  • Pointee : 解引用指针后匹配
  • AllOf/AnyOf : 组合多个匹配器(与/或)
  • Not : 取反匹配器

组合匹配器示例

EXPECT_THAT(value, AllOf(Gt(5), Lt(10)));  // 5 < value < 10
EXPECT_THAT(value, AnyOf(Eq(1), Eq(2)));   // value == 1 或 value == 2

最佳实践

  1. 优先使用显式比较EXPECT_THAT(value, Eq(5))EXPECT_THAT(value, 5) 更明确,可以避免隐式转换带来的意外结果。

  2. 利用组合匹配器:通过 AllOfAnyOfNot 等可以构建复杂的条件,使测试意图更清晰。

  3. 选择合适的浮点数匹配器:根据是否要处理 NaN 选择 DoubleEqNanSensitiveDoubleEq

  4. 利用容器匹配器的强大功能:相比简单的循环检查,使用 ElementsAreContains 等可以使测试代码更简洁。

  5. 为自定义类型实现匹配器:通过 MATCHER 宏可以轻松为自定义类型创建专用的匹配器。

自定义匹配器

虽然 GoogleTest 提供了丰富的内置匹配器,但有时我们需要为特定类型创建自定义匹配器:

MATCHER(IsEven, "") {
  return (arg % 2) == 0;
}

TEST(MyTest, EvenTest) {
  EXPECT_THAT(4, IsEven());
}

自定义匹配器可以极大地提高测试代码的可读性和可维护性。

总结

GoogleTest 的匹配器系统提供了强大而灵活的值验证机制,从简单的相等比较到复杂的容器、对象成员检查,几乎涵盖了所有测试场景。合理使用匹配器可以使测试代码更清晰、更易于维护,同时在测试失败时提供更有价值的诊断信息。掌握匹配器的使用是编写高质量测试代码的关键技能之一。

【免费下载链接】googletest 由 Google 开发的一款用于 C++ 的单元测试和模拟(mocking)框架 【免费下载链接】googletest 项目地址: https://gitcode.com/GitHub_Trending/go/googletest

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值