枚举类的GoogleTest测试错误打印

GoogleTest test error print of enum class

本文关键字:错误 打印 测试 GoogleTest 枚举      更新时间:2023-10-16

我使用GoogleTest 1.7.0版本来测试我的C++应用程序。我有一个枚举定义如下

namespace MyNamespace {
    enum class MyEnum {
        MyEnumValue,
        MyEnumValue2
    }
}

GoogleTest错误地打印了它的值,导致测试失败时出现以下错误消息:

的值:MyClass.MyMethodThatReturnsNum()

实际:4字节对象

应为:MyEnum::MyEnum值

即:4字节对象<02-00-00>

删除class关键字将生成具有枚举实际值的正确错误消息。这是GoogleTest的已知行为/错误吗?有办法解决这个问题吗?

MyClass my_class;
EXPECT_EQ(MyEnum::MyEnumValue, my_class.MyMethodThatReturnsEnum());

enum class MyEnum中定义常量时,将它们定义为对象用户定义类型MyEnum,没有从中进行隐式转换到任何积分类型。这是enum class目标,而不是Googletest假设您自动想要MyEnum类型的对象转换为整型以便插入输出流,如果您选择将该类型设置为enum class,而不仅仅CCD_ 7。

所以你观察到的并不是谷歌测试的错误。这只是谷歌测试使用某种类型T的用户定义对象的回退表示

std::ostream & operator<<(std::ostream &, T const &);

未定义。

如果要查看类型为enum class MyEnum的对象的积分值出现在谷歌测试的诊断程序中进行测试,你至少有两种方法。

一种方法是简单地将测试应用于对象的基本积分值,如:

main.cpp(1)

#include <gtest/gtest.h>
#include <type_traits>
enum class MyEnum {
    Value,
    Value2
};
auto as_integral(MyEnum me)
-> std::underlying_type<MyEnum>::type
{
    return static_cast<std::underlying_type<MyEnum>::type>(me);
}
TEST(foo,bar)
{
    EXPECT_EQ(as_integral(MyEnum::Value),as_integral(MyEnum::Value2));
}
int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

编译、链接和运行:

$ g++ -std=c++11 -Wall -Wextra -o gtester main.cpp -lgtest  -lpthread
$ ./gtester
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from foo
[ RUN      ] foo.bar
main.cpp:17: Failure
Expected equality of these values:
  as_integral(MyEnum::Value)
    Which is: 0
  as_integral(MyEnum::Value2)
    Which is: 1
[  FAILED  ] foo.bar (0 ms)
[----------] 1 test from foo (1 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (1 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] foo.bar
 1 FAILED TEST

另一种更好的方法是为Googletest提供一个定义:

std::ostream & operator<<(std::ostream &, MyEnum const &);

适合你的。然后谷歌测试将在其诊断中使用它,如:

main.cpp(2)

#include <gtest/gtest.h>
#include <type_traits>
#include <ostream>
enum class MyEnum {
    Value,
    Value2
};
auto as_integral(MyEnum me)
-> std::underlying_type<MyEnum>::type
{
    return static_cast<std::underlying_type<MyEnum>::type>(me);
}
std::ostream & operator<<(std::ostream & out, MyEnum me)
{
    return out << as_integral(me);
}
TEST(foo,bar)
{
    EXPECT_EQ(MyEnum::Value,MyEnum::Value2);
}
int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

编译、链接和运行:

$ g++ -std=c++11 -Wall -Wextra -o gtester main.cpp -lgtest  -lpthread
$ ./gtester
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from foo
[ RUN      ] foo.bar
main.cpp:23: Failure
Expected equality of these values:
  MyEnum::Value
    Which is: 0
  MyEnum::Value2
    Which is: 1
[  FAILED  ] foo.bar (0 ms)
[----------] 1 test from foo (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] foo.bar
 1 FAILED TEST

问题可能是enum classes(正式命名的作用域枚举)的大小不一定与enums(正式命名为未作用域的枚举)相同。

编译器决定哪种大小适合您的枚举。Enum classes具有默认大小。这就是enum classes易于转发声明的原因。

测试框架似乎没有区分这两者。

您需要实现自定义打印:https://github.com/google/googletest/blob/master/docs/advanced.md#teaching-谷歌测试如何打印你的价值

我在接口的模拟实现中提供了这些。