如何用Google Test检查std::type_info?std::any类型校验实践
针对std::any类型检查的单元测试方案
自定义Google Test匹配器(推荐方案)
自定义匹配器完全可行,能兼顾类型比较的可靠性和错误信息的可读性。核心思路是直接利用std::type_info的==运算符(标准允许直接比较引用,避免拷贝问题),同时在匹配器中添加友好的错误提示。
匹配器实现代码
#include <gtest/gtest.h> #include <typeinfo> #include <any> // 自定义匹配器:检查std::type_info是否与目标类型一致 MATCHER_P(IsOfType, expected_type, std::string(negation ? "isn't" : "is") + " of type " + expected_type.name()) { if (!(arg == expected_type)) { *result_listener << "but is of type " << arg.name(); return false; } return true; }
使用示例
TEST(AnyTypeTest, ValidDoubleType) { std::any x = 3.14; EXPECT_THAT(x.type(), IsOfType(typeid(double))); } TEST(AnyTypeTest, InvalidTypeCheck) { std::any x = "test string"; EXPECT_THAT(x.type(), IsOfType(typeid(int))); }
失败时会输出类似错误信息:
Expected: is of type i
Actual: isn't of type i (but is of type PKc)
(注:typeid.name()的输出格式由编译器决定,若需要更易读的类型名,可以配合abi::__cxa_demangle进行解码,这一步可选)
简化宏定义方案
如果不想写复杂的匹配器,也可以用宏封装比较逻辑,直接输出友好的错误信息:
宏定义代码
#include <gtest/gtest.h> #include <typeinfo> #include <any> #define EXPECT_TYPE_EQ(actual_type, expected_type) \ do { \ const std::type_info& actual = (actual_type); \ const std::type_info& expected = (expected_type); \ EXPECT_TRUE(actual == expected) \ << "Expected type: " << expected.name() \ << ", Actual type: " << actual.name(); \ } while (false)
使用示例
TEST(AnyTypeTest, ValidIntType) { std::any x = 42; EXPECT_TYPE_EQ(x.type(), typeid(int)); }
失败时的错误信息会直接显示预期和实际的类型名,清晰直观。
各方案优劣对比
EXPECT_THAT(x.type(), Eq(typeid(double))):无法编译,因为std::type_info不可拷贝,直接排除。EXPECT_EQ(x.type(), typeid(double)):可运行但错误信息是内存地址,完全无法定位问题,不推荐。- 比较
type().name():实现简单但不可靠,不同类型可能有相同的名字(比如部分编译器下const int和int的name输出一致),且输出格式依赖编译器,跨平台一致性差。 - 自定义匹配器/宏:既保留了
std::type_info直接比较的可靠性(标准定义的类型相等判断逻辑),又能输出可读的错误信息,完全满足批量测试的需求,是最优选择。
内容的提问来源于stack exchange,提问作者Jens
相关产品推荐
相关产品推荐

