The random ramblings of a techie

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
Facebook Twitter Digg Reddit Linkedin Email

, , , ,

Leave a Reply

Connect with:

Your email address will not be published. Required fields are marked *

Please type the characters of this captcha image in the input box

Please type the characters of this captcha image in the input box

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>