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