如何将GTest的UnorderedElementsAreArray与自定义Matcher链式结合?
解决GTest中自定义结构体向量的无序自定义匹配问题
核心思路
GTest的UnorderedElementsAreArray不仅支持传入值数组,还能接收匹配器数组。你只需要把每个期望值转换成对应的自定义匹配器,再传入该匹配器就能实现无序的、基于特定字段的向量元素匹配,完全不需要为结构体添加operator==。
具体实现步骤
假设你的自定义结构体和已编写的匹配器如下(可替换为你的实际代码):
// 自定义结构体 struct MyStruct { int id; std::string name; }; // 你已实现的自定义匹配器,此处以匹配id字段为例 MATCHER_P(MatchMyStructById, expected_id, "Matches MyStruct by id") { return arg.id == expected_id; }
1. 将期望值向量转换为匹配器向量
遍历你的期望值向量,为每个期望元素生成对应的自定义匹配器:
#include <vector> #include <algorithm> #include <gmock/gmock.h> // 你的实际期望值向量 std::vector<MyStruct> expected_vec = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}}; // 生成匹配器向量 std::vector<testing::Matcher<MyStruct>> matcher_vec; std::transform( expected_vec.begin(), expected_vec.end(), std::back_inserter(matcher_vec), [](const MyStruct& s) { return MatchMyStructById(s.id); } );
2. 结合UnorderedElementsAreArray完成断言
直接将匹配器向量传入UnorderedElementsAreArray即可完成无序匹配:
// 你的实际值向量 std::vector<MyStruct> actual_vec = {{2, "Bob"}, {3, "Charlie"}, {1, "Alice"}}; EXPECT_THAT(actual_vec, testing::UnorderedElementsAreArray(matcher_vec));
扩展:匹配多个字段
如果需要同时匹配结构体的多个字段,只需调整自定义匹配器(比如用MATCHER_P2),再按同样逻辑转换即可:
// 匹配id和name两个字段的自定义匹配器 MATCHER_P2(MatchMyStruct, expected_id, expected_name, "Matches MyStruct by id and name") { return arg.id == expected_id && arg.name == expected_name; } // 转换时传入多个字段生成匹配器 std::vector<testing::Matcher<MyStruct>> matcher_vec; std::transform( expected_vec.begin(), expected_vec.end(), std::back_inserter(matcher_vec), [](const MyStruct& s) { return MatchMyStruct(s.id, s.name); } );
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

