Click here to Skip to main content
15,891,718 members
Articles
(untagged)

Google’s gtest Not Handling Friend Tests Correctly

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
29 Oct 2012CPOL 10.8K   1  
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:

C++
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:

C++
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 of 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:

C++
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)


Written By
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 --