gtest使用被测试类的非public成员

转自: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成员函数吗?经过检验,答案是肯定的。




你可能感兴趣的:(gtest使用被测试类的非public成员)