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 namespaceNeither 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