Google’s gtest not handling friend tests correctly

I was using Google’s gtest unit test framework today and I found an annoying problem – you can’t properly friend test methods that are in a different namespace than the class being tested.

Here is a typical situation:

namespace MyNamespace
{
   class MyClass
   {
      public:
         MyClass(int inData): data(inData){}
      private:
         int data;
   };
}//end namespace

namespace MyNamespace
{
namespace TEST
{
   class MyTestClassFixture
   {
      static const int fixtureData;
   }
   static const MyTestClassFixture::fixtureData = 5;

   TEST_F(MyTestClassFixture, TestEqual)
   {
      MyClass testClass(5);
      ASSERT_EQ(fixtureData, testClass.data);
   }
}
}


Since the unit test needs to access the private data of the class, it would seem logical to make it a friend class. The framework provides a macro that does that – FRIEND_TEST, so you might be tempted to do something like this:

namespace MyNamespace
{
//Forward declare the tests
namespace TEST
{
   TEST_F(MyTestClassFixture, TestEqual)
}
   class MyClass
   {
      public:
         MyClass(int inData): data(inData){}
         FRIEND_TEST(MyTestClassFixture, TestEqual)
      private:
         int data;
   };
}//end namespace

Neither of those works. FRIEND_TEST macro extends to friend class  MyTestClassFixture_TestEqual_Test, which obviously does not include the namespace of the test class. TEST_F also expands to something that’s not of any use.

The only way I could think off to go around this very annoying problem, was to roll my own macros – one to get the name of the class, and another to do the forward declaration:

namespace MyNamespace
{
//Forward declare the tests
namespace TEST
{
   #define GET_CLASS_NAME(test_case_name, test_name)\
   test_case_name##_##test_name##_Test

   #define GET_DECORATED_CLASS_NAME(namespace, test_case_name, test_name)\
   namespace::GET_CLASS_NAME(test_case_name, test_name)

   class GET_CLASS_NAME(MyTestClassFixture, TestEqual);
}
   class MyClass
   {
      public:
         MyClass(int inData): data(inData){}
         friend class GET_DECORATED_CLASS_NAME(TEST, MyTestClassFixture, TestEqual);
      private:
         int data;
   };
}//end namespace

Leave a Reply