【问题标题】:Use enum classes with Boost Test将枚举类与 Boost 测试一起使用
【发布时间】:2015-06-16 06:28:20
【问题描述】:

我有一个想在单元测试中使用的枚举类:

enum class MyEnumClass
{
    MyEntryA,
    MyEntryB
};

我想如下使用它:

MyEnumClass myEnumValue = MyEnumClass::MyEntryA;
BOOST_CHECK_EQUAL(myEnumValue, MyEnumClass::MyEntryB);

但是我得到了这个错误,显然是因为 boost test 正在尝试输出值:

include/boost/test/test_tools.hpp:326:14: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
         ostr << t; // by default print the value
              ^

添加丑陋的static_cast“解决”了问题:

BOOST_CHECK_EQUAL(static_cast<int>(myEnumValue), static_cast<int>(MyEnumClass::MyEntryB));

但我想避免对每个枚举类都这样做。我还想避免为每个枚举类定义 &lt;&lt; 流运算符。

有没有更简单的方法来使用枚举类和 boost 测试?

或者其他单元测试框架有更好的方法来处理枚举类?

【问题讨论】:

标签: c++ boost-test enum-class


【解决方案1】:

另一种解决方案是使用BOOST_CHECK(myEnumValue == MyEnumClass::MyEntryB),而不是BOOST_CHECK_EQUAL。这对我有用,我假设对于简单的真/假检查,boost 不需要打印出枚举类。

【讨论】:

  • 这是侵入性最小的选项。如果您不能/不想为类提供
【解决方案2】:

您可以使用BOOST_TEST_DONT_PRINT_LOG_VALUE() 禁用相关类型的打印。来自Boost docs

typedef std::pair<int,float> pair_type;

BOOST_TEST_DONT_PRINT_LOG_VALUE( pair_type )

在这种情况下,如果您得到不匹配,测试错误消息会告诉您,但不会打印实际的不同值。

【讨论】:

  • 另外,请注意BOOST_TEST_DONT_PRINT_LOG_VALUE() 不能嵌入到命名空间中(至少在 Boost 1.63.0 中)。 BOOST_TEST_DONT_PRINT_LOG_VALUE(MyEnumClass) mynamespace { ... } 可以,但mynamespace { BOOST_TEST_DONT_PRINT_LOG_VALUE(MyEnumClass) ... } 不行。
  • @dbank:是因为所讨论的类型不是命名空间的一部分吗?如果您执行BOOST_TEST_DONT_PRINT_LOG_VALUE(::MyEnumClass) 之类的操作怎么办?
  • 我不知道为什么,但是当我将 BOOST_TEST_DONT_PRINT_LOG_VALUE(MyEnumClass) 放入命名空间时,g++ 会在 BOOST_TEST_DONT_PRINT_LOG_VALUE 上给出宏扩展错误,并会导致文件中较低的任何 boost 宏给出错误,比如BOOST_AUTO_TEST_SUITEBOOST_FIXTURE_TEST_CASE
  • 另外,在我的例子中,枚举类声明/定义在命名空间中。
  • 啊,我明白了,做mynamespace { BOOST... } 试图构造一个类型mynamespace::boost::test_tools::...,这就是问题所在。不确定这是否会被视为错误 - 您可以尝试在 Boost 邮件列表中询问。
【解决方案3】:

问题在于 Boost.Test 必须打印值以防它们不相等,并且它在流上使用 operator&lt;&lt; 来做到这一点。

在这种情况下,没有比在std::ostream 上简单定义operator&lt;&lt; 或将static_cast 定义为int 更简洁的方法了,我可以看到。

另一方面,像 Catch 这样的库没有这个要求,他们可能使用一些宏魔法来完成它。

【讨论】:

    【解决方案4】:

    解决方案:

    enum class MyEnumClass {
      MyEntryA,
      MyEntryB
    };
    
    MyEnumClass myEnumValue = MyEnumClass::MyEntryA;
    BOOST_TEST((myEnumValue == MyEnumClass::MyEntryA)); // Note extra pair of brackets
    BOOST_TEST((myEnumValue == MyEnumClass::MyEntryB)); // Note extra pair of brackets
    

    结果:

    info: check (myEnumValue == MyEnumClass::MyEntryA) has passed
    error: in "Suite/Test": check (myEnumValue == MyEnumClass::MyEntryB) has failed
    

    详情:

    1. 使用 BOOST_TEST() 作为测试通用宏 (Assertion Boost Test Universal Macro):

      • BOOST_TEST // 或 BOOST_TEST_CHECK
      • BOOST_TEST_REQUIRE
      • BOOST_TEST_WARN
    2. 似乎应该将作用域枚举(枚举类)添加到需要一对额外括号的Limitations and workaround

    【讨论】:

      【解决方案5】:

      这是我的解决方案(很简单)

      将其添加到测试文件的顶部

      #define CHECK_ENUM_CLASS_EQUAL(L, R) BOOST_CHECK_EQUAL(static_cast<int>(L), static_cast<int>(R))
      

      例子:

      CHECK_ENUM_CLASS_EQUAL(a, MyEnumClass::MyEntryA);
      

      【讨论】:

        猜你喜欢
        • 2011-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多