转自: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(). }
例如,如果被测试类放在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成员函数吗?经过检验,答案是肯定的。