转自:https://code.google.com/p/googletest/wiki/AdvancedGuide#Private_Class_Members
通过将FRIEND_TEST(TestCaseName,TestName);宏放入被测试类,可以让gtest的测试类能访问到被测试类的非public成员:
// foo.h
#include "gtest/gtest_prod.h"
// Defines FRIEND_TEST.
class Foo {
...
private:
FRIEND_TEST(FooTest, BarReturnsZeroOnNull);
int Bar(void* x);
};
// foo_test.cc
...
TEST(FooTest, BarReturnsZeroOnNull) {
Foo foo;
EXPECT_EQ(0, foo.Bar(NULL));
// Uses Foo's private member Bar().
}
注意:对于这种“gtest使用被测试类的非public成员”的情况,如果被测试类在某个namespace中,那么测试类也要放在相同的namespace中
例如,如果被测试类放在my_namespace的命名空间中
namespace my_namespace {
class Foo {
friend class FooTest;
FRIEND_TEST(FooTest, Bar);
FRIEND_TEST(FooTest, Baz);
...
definition of the class Foo
...
};
} // namespace my_namespace
那么,测试类也要放在my_namespace命名空间中
namespace my_namespace {
class FooTest : public ::testing::Test {
protected:
...
};
TEST_F(FooTest, Bar) { ... }
TEST_F(FooTest, Baz) { ... }
} // namespace my_namespace
【Yasi】
对于上面的例子,如果编译时提示“FooTest类没有定义”,实际上说明FRIEND_TEST宏没有被找到,而不是什么“FooTest类没有定义”,这时,要检查Makefile的include路径,确保gcc能找到"gtest/gtest_prod.h"
【Yasi】
上面的做法,有个缺点:会在被测试类的头文件中引入gtest相关内容,比如包含头文件、FRIEND_TEST类申明;可能还会导致主工程编译不过,从而需要加条件编译开关。
其实,还有一种更简便方法:被测试的源文件和Makefile不需要任何修改,只要定义下面有个头文件CxxTestDefs.h,然后在测试类的.cpp文件中#include "CxxTestDefs.h"就可以了
#ifndef __CXX_TEST_H__
#define __CXX_TEST_H__
#define private public
#define protected public
#endif //__CXX_TEST_H__
注意:
1)测试类的.cpp文件中,#include "CxxTestDefs.h"必须放在被测试类的#include行的上面,这样被测试类中的private, protected关键字就会被替换成public,测试类就能访问了;如果 #include "CxxTestDefs.h" 放在被测试类的#include行的下面,编译器还是会报错!
2)可能有人会怀疑,只替换头文件中的private, protected关键字,而不重新编译被测试类,就能访问到被测试类的非public成员函数吗?经过检验,答案是肯定的。