Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

Google’s gtest not handling friend tests correctly

, 29 Oct 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
You can’t properly friend test methods that are in a different namespace than the class being tested.

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

VentsyV
Software Developer
United States United States
I've been developing software for about 5 years now, specializing mostly in industrial and scientific programming. I'm experienced in C/C++ and C# both on Windows and Linux. I'm also fairly experienced in SQL as well.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 29 Oct 2012
Article Copyright 2012 by VentsyV
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid