如何使用gtest测试带有多个模板参数的c ++模板类?

时间:2015-04-01 03:01:51

标签: c++ templates googletest

我想用gtest测试模板类。我在gtest手册中阅读了TYPED_TEST s并查看了他们引用的官方示例(samples\sample6_unittest.cc)。示例中的此模板只有一个模板参数。 但是,我的代码有两个模板参数,我该如何测试呢?

我有以下代码:

// two element type
template <typename E, typename F>
class QueueNew
{
public:
    QueueNew() {}
    void Enqueue(const E& element) {}
    E* Dequeue() {}
    F size() const 
    {
        return (F)123;
    }
};

我在下面编写了测试代码:

template <class E, class F>
QueueNew<E, F>* CreateQueue();

template <>
QueueNew<int, int>* CreateQueue<int, int>()
{
    return new QueueNew < int, int > ;
}
template <>
QueueNew<char, char>* CreateQueue<char, char>()
{
    return new QueueNew < char, char > ;
}

template <class E, class F>
class QueueTestNew;

template <class E>
class QueueTestNew<E, int> : public testing::Test
{
protected:
    QueueTestNew() : queue(CreateQueue<E, int>()){}
    virtual ~QueueTestNew(){ delete queue; }
    QueueNew<E, int>* const queue;
};

template <class E>
class QueueTestNew<char, E> : public testing::Test
{
protected:
    QueueTestNew() : queue(CreateQueue<char, E>()){}
    virtual ~QueueTestNew(){ delete queue; }
    QueueNew<char, E>* const queue;
};

// The list of types we want to test.
typedef ::testing::Types <char, int> Implementations;

TYPED_TEST_CASE(QueueTestNew, Implementations);

TYPED_TEST(QueueTestNew, DefaultConstructor)
{
    EXPECT_EQ(123u, this->queue->size());
}

但在构建时,我收到错误:

error C2976: 'QueueTestNew' : too few template arguments
see declaration of 'QueueTestNew'
...

我认为我的gtest测试模板方法是错误的,所以我应该怎么做?

2 个答案:

答案 0 :(得分:10)

一个技巧是让gtest看到一个带有嵌套类型的单一类型参数。为此,您可以定义模板化结构,例如:

template <typename A, typename B>
struct TypeDefinitions
{
  typedef typename A MyA;
  typedef typename B MyB;
};

您可以将其传递给您的打字测试夹具:

template <class T>
class QueueTestNew : public testing::Test
{
protected:
  QueueTestNew() : queue(CreateQueue<typename T::MyA, typename T::MyB>()){}
  virtual ~QueueTestNew(){ delete queue; }
  QueueNew<typename T::MyA, typename T::MyB>* const queue;
};

// The list of types we want to test.
typedef ::testing::Types <TypeDefinitions<char,char>,
                          TypeDefinitions<int,int> > Implementations;

TYPED_TEST_CASE(QueueTestNew, Implementations);

TYPED_TEST(QueueTestNew, DefaultConstructor)
{
  typename TypeParam::MyA someA; // if you need access to the subtypes in the test itself

  EXPECT_EQ(123u, this->queue->size());
}

答案 1 :(得分:5)

一个可能也可行且不需要自定义结构的示例正在使用std::tuples

template <class T>
class TestThreeParams : public testing::Test {};

typedef ::testing::Types <std::tuple<float64_t, float32_t, int16>, std::tuple<int64, int8, float32_t> > Implementations;

TYPED_TEST_CASE(TestThreeParams, Implementations);

TYPED_TEST(TestThreeParams, MaximumTest)
{
    using A = std::tuple_element<0, decltype(TypeParam())>::type;
    using B = std::tuple_element<1, decltype(TypeParam())>::type;
    using C = std::tuple_element<2, decltype(TypeParam())>::type;

    bool test = (Max<A, B, C>(A(-5), B(2), C(5)) == 5);
    EXPECT_TRUE(test);
}