'gtest - testing template class

I want to test a template class with gtest. I read about TYPED_TESTs in Google Test manual and looked at official example they reference, but still can't wrap my head around getting an object of template class instantiated in my test.

Suppose the following simple template class:

template <typename T>
class Foo
{
public:
    T data ;
};

In testing class we declare

typedef ::testing::Types<int, float> MyTypes ;

Now how can I instantiate an object of class Foo for Ts listed in MyTypes in a test? E.g.

TYPED_TEST(TestFoo, test1)
{
    Foo<T> object ;
    object.data = 1.0 ;

    ASSERT_FLOAT_EQ(object.data, 1.0) ;
}


Solution 1:[1]

Inside a test, refer to the special name TypeParam to get the type parameter. So you could do

TYPED_TEST(TestFoo, test1)
{
    Foo<TypeParam> object ; // not Foo<T>
    object.data = 1.0 ;

    ASSERT_FLOAT_EQ(object.data, 1.0) ;
}

Solution 2:[2]

Since I couldn't figure out on my own how to combine TemplateRex's answer with Puchatek's original snippet, here's a complete compilable example. I got this by reading GTest's own comments, which are pretty helpful.

Put the following into test.cpp:

#include <gtest/gtest.h>
#include <regex>
#include <vector>

using vector_typelist = testing::Types<char, int*, std::regex>;
template<class> struct vector_suite : testing::Test {};
TYPED_TEST_SUITE(vector_suite, vector_typelist);

TYPED_TEST(vector_suite, bigness)
{
    std::vector<TypeParam> v;
    EXPECT_TRUE(sizeof(v) >= sizeof(TypeParam));
}

Compile with the appropriate -I and -l options. This might look something like:

g++ -std=c++14 -I/usr/local/include test.cpp -L/usr/local/lib -lgtest -lgtest_main

or (if you use pkg-config):

g++ -std=c++14 $(pkg-config --cflags gtest) test.cpp $(pkg-config --libs gtest_main)

Run the executable and you should see something like this:

$ ./a.out
Running main() from /foobar/gtest_main.cc
[==========] Running 3 tests from 3 test suites.
[----------] Global test environment set-up.
[----------] 1 test from vector_suite/0, where TypeParam = char
[ RUN      ] vector_suite/0.bigness
[       OK ] vector_suite/0.bigness (0 ms)
[----------] 1 test from vector_suite/0 (0 ms total)

[----------] 1 test from vector_suite/1, where TypeParam = int*
[ RUN      ] vector_suite/1.bigness
[       OK ] vector_suite/1.bigness (0 ms)
[----------] 1 test from vector_suite/1 (0 ms total)

[----------] 1 test from vector_suite/2, where TypeParam = std::basic_regex<char, std::__1::regex_traits<char> >
[ RUN      ] vector_suite/2.bigness
test.cpp:12: Failure
Value of: sizeof(v) >= sizeof(TypeParam)
  Actual: false
Expected: true
[  FAILED  ] vector_suite/2.bigness, where TypeParam = std::basic_regex<char, std::__1::regex_traits<char> > (0 ms)
[----------] 1 test from vector_suite/2 (0 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 3 test suites ran. (0 ms total)
[  PASSED  ] 2 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] vector_suite/2.bigness, where TypeParam = std::basic_regex<char, std::__1::regex_traits<char> >

 1 FAILED TEST

(I put in this failed test purely to demonstrate what happens when a typed test fails. In fact sizeof(std::vector<std::regex>) is indeed smaller than sizeof(std::regex).)


Be aware that TYPED_TEST produces a family of test suites with related but non-identical names. There is no single vector_suite anymore:

$ ./a.out --gtest_filter=vector_suite.*
Running main() from /foobar/gtest_main.cc
Note: Google Test filter = vector_suite.*
[==========] Running 0 tests from 0 test suites.
[==========] 0 tests from 0 test suites ran. (0 ms total)
[  PASSED  ] 0 tests.

Instead there are vector_suite/0, vector_suite/1, and vector_suite/2:

$ ./a.out --gtest_filter=vector_suite/0.*
Running main() from /foobar/gtest_main.cc
Note: Google Test filter = vector_suite/0.*
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from vector_suite/0, where TypeParam = char
[ RUN      ] vector_suite/0.bigness
[       OK ] vector_suite/0.bigness (0 ms)
[----------] 1 test from vector_suite/0 (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TemplateRex
Solution 2