nya*_*108 6 c++ googletest googlemock c++17
我有一个正在通知侦听器的数据结构。在它的许多变量中,它有一个可选的 double 代表一个角度:
struct Data
{
// ...other data fields
std::optional<double> angle;
// ...other data fields
};
Run Code Online (Sandbox Code Playgroud)
我想检查监听器是否被正确调用angle。我正在使用Google Test Framework,所以我在这里定义了自己的匹配器:
MATCHER_P( HasAngle, angle, "" )
{
if ( !arg.angle.has_value( ) )
{
return false;
}
return arg.angle.value( ) == angle;
}
Run Code Online (Sandbox Code Playgroud)
并检查我的侦听器是否正在使用预期值进行调用。
EXPECT_CALL( listener, on_event( HasAngle( 45.0 ) ) ).Times( AtLeast( 1 ) );
Run Code Online (Sandbox Code Playgroud)
最终,监听器没有被调用并具有预期的值,但打印输出确实不可读:
Expected arg #0: has angle 45
Actual: 128-byte object <75-85 4D-52 FB-21 F9-BF 47-D9 48-53 FB-21 09-C0 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 01-17 23-83 FD-7F 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00>
Run Code Online (Sandbox Code Playgroud)
实际价值难以理解。我没想到该框架默认不支持 C++17 类型,因此我开始阅读Google Test Framework Cookbook,并尝试添加自己的PrintTo重载,如下所示:
void
PrintTo( const std::optional< double >& opt, std::ostream* os )
{
if ( !opt )
{
*os << "std::nullopt";
}
else
{
*os << *opt;
}
}
Run Code Online (Sandbox Code Playgroud)
不用说,这没有帮助。我非常确定的是,由于输出表明128-byte object它正在尝试打印鞋底std::optional<double>而不是整个struct Data,它比这大得多,但尽管超载,但它并没有成功PrintTo。
如果您使用匹配器, GoogleTest 会打印std::optional值Optional(m)。
测试示例:
TEST_F(MyClassTests, myFunctionTest)
{
std::optional<std::string> actual_value = "foo";
std::string expected_value = "bar";
EXPECT_THAT(actual_value, testing::Optional(expected_value));
}
Run Code Online (Sandbox Code Playgroud)
输出将类似,但在神秘 128-byte object <75-85 4D-52 FB-21 F9-BF...文本之后,将另外打印包含的值:
TEST_F(MyClassTests, myFunctionTest)
{
std::optional<std::string> actual_value = "foo";
std::string expected_value = "bar";
EXPECT_THAT(actual_value, testing::Optional(expected_value));
}
Run Code Online (Sandbox Code Playgroud)
如果您希望 astd::optional出现std::nullopt在测试用例中,您很可能会这样做:
EXPECT_EQ(actual_value, std::nullopt);
Run Code Online (Sandbox Code Playgroud)
actual_value如果确实有值,测试将会失败。但同样,实际值不会被打印。作为解决方法,您可以像这样实施测试:
if (actual_value) {
FAIL() << "actual_value is not std::nullopt, but: " << actual_value.value();
}
Run Code Online (Sandbox Code Playgroud)
在测试中为您的类型定义标准输出运算符应该会有所帮助并在 gmock 错误消息中使用
template <class T>
std::ostream & operator<<(std::ostream & os, std::optional<T> const & opt)
{
if (opt) return os << opt.value();
return os << "EMPTY";
}
Run Code Online (Sandbox Code Playgroud)