枚举的模板Googletest


关于如何为标准类型编写模板化测试,C++Googletest有相当好的文档。然而,我需要的是编写测试,其中模板是enum,实现是该enum的特定值。我不知道如何使用可用的工具来实现这一点(或者是否可能(。

复制这些例子,我一直在尝试以下内容:

enum Dinosaur { Trex = 0, Stegosaur = 1, Triceratops = 2 };
using MyDinosaurs = ::testing::Types<
Dinosaur::Trex, 
Dinosaur::Stegosaur, 
Dinosaur::Triceratops>; // This line does not compile, since Dinosaur::Trex etc aren't actually types

template <Dinosaur Dinosaur_T>
class DinosaurTest : public ::testing::Test 
{ 
private:
DinosaurFactory<Dinosaur_T> m_dinosaurFactory;
};
TYPED_TEST_SUITE(DinosaurTest, MyDinosaurs);
TYPED_TEST_P(DinosaurTest, DinosaurEnumTest) 
{ 
ASSERT_NE(nullptr, m_dinosaurFactory.Create()); 
}
REGISTER_TYPED_TEST_SUITE_P(DinosaurTest, DinosaurEnumTest);
INSTANTIATE_TYPED_TEST_SUITE_P(MyDinosaurTestSuite, DinosaurTest, MyDinosaurs); // This line then also does not compile, since 'MyDinosaurs' isn't a valid list of types

如何使这种方式的测试适用于枚举?

您可以使用std::integral_constant实际提供类型而不是值:

using MyDinosaurs = ::testing::Types<
std::integral_constant<decltype(Dinosaur::Trex),Dinosaur::Trex>, 
std::integral_constant<decltype(Dinosaur::Trex), Dinosaur::Stegosaur>,
std::integral_constant<decltype(Dinosaur::Trex), Dinosaur::Triceratops>>;

你可以在你的std::integral_constant上调用::value来实际获得enum value,所以,把你的夹具修改为:

template <typename T>
class DinosaurTest : public ::testing::Test 
{ 
public:
DinosaurFactory<T::value> m_dinosaurFactory; // T::value is your enum type
}

通过这些修改,您就设置好了。您可以在此处查看基于问题的完整示例:https://godbolt.org/z/97eszrMsK

注意:我不确定是否还有其他方法,我还没有找到。

您也可以使用此方法代替std::integral_constant:

template <Dinosaur N>
struct EnumValue{
static const Dinosaur value = N;
};
using MyDinosaurs = ::testing::Types<
EnumValue<Dinosaur::Trex>, 
EnumValue<Dinosaur::Stegosaur>,
EnumValue<Dinosaur::Triceratops>>;

其余内容同上。

您确定要使用类型而不是作为测试参数吗?

在我看来,您需要测试枚举中给定不同Dinosaur类型的DinosaurFactory。所以,也许你的DinosaurFactory不应该是一个模板,但它应该把类型作为一个参数?

如果是这种情况,您可以使用参数化测试而不是类型化测试,如下所示:

enum class Dinosaur { Trex = 0, Stegosaur = 1, Triceratops = 2 };
class CDinosaur {
public:
CDinosaur(Dinosaur type) : m_type(type) {}
Dinosaur m_type;
};
class DinosaurFactory {
public:
CDinosaur* Create(Dinosaur type) { return new CDinosaur(type); }
};
class DinosaurTest : public testing::TestWithParam<Dinosaur> {
public:
DinosaurFactory m_dinosaurFactory;
};
// This will create multiple tests.
TEST_P(DinosaurTest, DinosaurEnumTest) {
auto type = GetParam();
auto actual = m_dinosaurFactory.Create(type);
ASSERT_NE(nullptr, actual);
if (actual != nullptr) {
delete actual;
}
}
INSTANTIATE_TEST_SUITE_P(DinosaurTestWithFactory, DinosaurTest,
testing::Values(Dinosaur::Trex, Dinosaur::Stegosaur,
Dinosaur::Triceratops));

现场示例:https://godbolt.org/z/MdjbrTfEP

旁注:

  1. 使用enum class而不是enum
  2. 不要忘记删除m_dinosaurFactory.Create产生的指针或使用unique_ptr

相关内容

  • 没有找到相关文章

最新更新