C++ 具有不完整模板的googletest类型参数化测试

C++ 具有不完整模板的googletest类型参数化测试,c++,googletest,C++,Googletest,假设我有一个比较模板类的两个实例化的测试: TEST_F(fooSuite, fooTest) { U<A> tA; U<B> tB; someCheck(tA, tB); } 直觉上,我想写一些类似的东西: template <class TestType> class fooSuite { }; TYPED_TEST_P(fooSuite, fooTest) { TypeParam<A> tA; Ty

假设我有一个比较模板类的两个实例化的测试:

TEST_F(fooSuite, fooTest) {
    U<A> tA;
    U<B> tB;
    someCheck(tA, tB);
}
直觉上,我想写一些类似的东西:

template <class TestType>
class fooSuite { };

TYPED_TEST_P(fooSuite, fooTest) {
    TypeParam<A> tA;
    TypeParam<B> tB;
    someCheck(tA, tB);
}

REGISTER_TYPED_TEST_SUITE_P(fooSuite, fooTest);

using TypesToTest = ::testing::Types<U, V>
INSTANTIATE_TYPED_TEST_SUITE_P(fooPrefix, fooSuite, TypesToTest);
模板
类{};
打字测试(fooSuite,fooTest){
TypeParam-tA;
TypeParam-tB;
某些检查(tA、tB);
}
注册类型测试套件(fooSuite,fooTest);
使用TypesToTest=::测试::类型
实例化类型化测试套件(fooPrefix、fooSuite、TypesToTest);
当然,这无法编译,因为
U
V
需要使用
表达式在此
中使用模板参数

如果没有一个主要的解决方法来创建包装类来传递,这是可能的吗

如果没有一个主要的解决方法来创建包装类来传递,这是可能的吗

从文件上看,答案是:不,你不能。问题是
TestingTypes
接受类型,但您希望传递模板。我能看到的唯一解决方案是创建一个简单的包装器类型,将感兴趣的模板放入测试函数中,并在那里用所需的模板参数实例化它

免责声明:我对谷歌测试还不够熟悉,也许有办法做到这一点

然而,根据您对“主要解决方法”的确切含义,下面的代码说明了一种可能的方法,我认为这应该是可行的。我认为这一努力还不错

template <class T>
class U { };

template <class T>
class V {  };

class A{};
class B{};

template<template<class> typename UorV>
struct TemplateHolder {
    template<class Arg>
    using type = UorV<Arg>;
};

template<class T, class Arg>
using instantiate_t = typename T::template type<Arg>;

// Mimick what I suspect the google testing::Types and TypeParam are. 
template<class... Ts>
struct TestingTypes {};

using types_to_test = TestingTypes<TemplateHolder<U>, TemplateHolder<V>>;



int main( void ) {

    using TypeParam = TemplateHolder<U>;
    using ActualTypeToTestA = instantiate_t<TestingType, A>;
    using ActualTypeToTestB = instantiate_t<TestingType, B>;

    static_assert(std::is_same_v<ActualTypeToTestA, U<A>>);
    static_assert(std::is_same_v<ActualTypeToTestB, U<B>>);
    return 0;
}
模板
类U{};
样板
第V类{};
A类{};
B类{};
样板
结构模板持有者{
样板

使用type=UorV

可以使用
std::tuple
作为测试夹具的模板参数,这将允许传递完整的类型

template <typename Tuple>
class FooSuite : public ::testing::Test
{
public:
    template<typename TA, typename TB>
    void SomeCheck(TA tA, TB tB)
    {
        // Check expectations here
    }
};

TYPED_TEST_SUITE_P(FooSuite);

TYPED_TEST_P(FooSuite, FooTest) {
    using TA = typename std::tuple_element<0, TypeParam>::type;
    using TB = typename std::tuple_element<1, TypeParam>::type;
    TA tA;
    TB tB;
    this->SomeCheck(tA, tB);
}

REGISTER_TYPED_TEST_SUITE_P(FooSuite, FooTest);

using TypesToTest = Types<
    std::tuple<U<A>, U<B>>,
    std::tuple<V<A>, V<B>>
>;

INSTANTIATE_TYPED_TEST_SUITE_P(FooPrefix, FooSuite, TypesToTest);
模板
类FooSuite:public::testing::Test
{
公众:
样板
无效检查(TA TA、TB TB)
{
//在这里检查期望值
}
};
打字测试套件(FooSuite);
打字测试(FooSuite,FooTest){
使用TA=typename std::tuple\u元素::type;
使用TB=typename std::tuple\u元素::type;
TA TA;
结核病;
这->一些检查(tA、tB);
}
注册类型测试套件(FooSuite,FooTest);
使用TypesToTest=Types<
std::tuple,
std::tuple
>;
实例化类型化测试套件(FooPrefix、FooSuite、TypesToTest);

您的U和V不是不完整的类型,它们是模板。我从未使用过类型化测试,但在快速查看文档后,您应该将类型注入测试,而不是模板。是的,“不完整类型”是错误的描述。但是,问题是如果没有模板参数,我不能在using语句中简单地使用
U
V
。我重新表述了问题的这一部分。
template <typename Tuple>
class FooSuite : public ::testing::Test
{
public:
    template<typename TA, typename TB>
    void SomeCheck(TA tA, TB tB)
    {
        // Check expectations here
    }
};

TYPED_TEST_SUITE_P(FooSuite);

TYPED_TEST_P(FooSuite, FooTest) {
    using TA = typename std::tuple_element<0, TypeParam>::type;
    using TB = typename std::tuple_element<1, TypeParam>::type;
    TA tA;
    TB tB;
    this->SomeCheck(tA, tB);
}

REGISTER_TYPED_TEST_SUITE_P(FooSuite, FooTest);

using TypesToTest = Types<
    std::tuple<U<A>, U<B>>,
    std::tuple<V<A>, V<B>>
>;

INSTANTIATE_TYPED_TEST_SUITE_P(FooPrefix, FooSuite, TypesToTest);