枚举类的GoogleTest测试错误打印

时间:2015-02-05 14:12:59

标签: c++ unit-testing c++11 enums googletest

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

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

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

  

价值:MyClass.MyMethodThatReturnsEnum()

     

实际:4字节对象

     

预期:MyEnum :: MyEnumValue

     

其中:4字节对象< 02-00 00-00>

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

MyClass my_class;

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

3 个答案:

答案 0 :(得分:2)

问题可能是enum classes(官方命名为范围的枚举)不一定与enums(官方命名为无范围的枚举)具有相同的大小。

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

看起来测试框架没有区分这两者。

答案 1 :(得分:1)

您需要实施自定义打印:https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#teaching-googletest-how-to-print-your-values

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

答案 2 :(得分:0)

enum class MyEnum中定义常量时,将它们定义为对象 用户定义类型的 MyEnum,没有隐式转换 任何整数类型。那是enum class的目标 让Googletest假设您要自动获取MyEnum类型的对象 转换为整数类型以插入输出 流,如果您选择将其键入enum class,而不仅仅是 enum

因此,您观察到的不是Googletest错误。只是使用它的Googletest 类型为T的用户定义对象的后备表示形式,

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

未定义。

如果要查看enum class MyEnum类型的对象的整数值 出现在Googletest的测试诊断中,您至少有两种方法。

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

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 &);

适合您。然后Googletest将在诊断程序中使用它,如下所示:

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