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;
};
}
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
{
namespace TEST
{
TEST_F(MyTestClassFixture, TestEqual)
}
class MyClass
{
public:
MyClass(int inData): data(inData){}
FRIEND_TEST(MyTestClassFixture, TestEqual)
private:
int data;
};
}
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:
namespace MyNamespace
{
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;
};
}