1

我试图弄清楚 FRIEND_TEST 在 Google 测试中的工作原理。 https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#testing-private-code

我正在查看以下项目,试图在我的代码中实现它:

// 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().
}

在上面的代码中,我看不到的部分是 foo_test.cc 必须包含 foo.h,才能访问 Foo 和 Bar()。[也许它对谷歌的工作方式不同?在我的代码中,我必须包含它]

这将导致循环依赖...

我错过了什么吗?

编辑:代码示例:(修复后重新编辑 - 解决方案将测试文件从 *.h 更改为 *.cpp):

项目 ppppp - 文件 myfile.h:

class INeedToBeTested
{
public:
  extern friend class blah_WantToTestThis_Test;
  INeedToBeTested();
  INeedToBeTested(INeedToBeTested* item);
  INeedToBeTested(OtherClass* thing, const char* filename);
  ~INeedToBeTested();
  bool Testable();
  std::string MoreTestable();

private:
  int WantToTestThis();
};

项目 ppppp_gtest,文件 myFile_gtest.cpp:

#pragma once
#include "gtest/gtest.h"
#include "myfile.h" //property sheet adds include locations
#include "otherclass.h"

  class blah: public ::testing::Test{
  // declarations, SetUp, TearDown to initialize otherclass thing, std::string filename
  }
  TEST_F(blah, WantToTestThis)
      {
        INeedToBeTested item(thing, filename.c_str());
        item.WantToTestThis();   // inaccessible when this content is in header file
      }

在我努力让它工作的过程中,我还尝试创建一个包装类(这也只在 cpp 中有效,而不是在 header 中);虽然它需要将private更改为protected,但它不需要在每个新测试的测试代码中添加额外的声明:

// option: create wrapper (change private to protected first) 
  class INeedToBeTestedWrapper:public INeedToBeTested 
      {
      public:
         INeedToBeTestedWrapper(OtherClass* thing, std::string filename):
            INeedToBeTested(OtherClass* thing, filename.c_str());
      public:
         using INeedToBeTested::WantToTestThis;
      };

      TEST_F(blah, WantToTestThis)
      {
        INeedToBeTestedWrapper item(thing, filename);
        item.WantToTestThis();   
      }
4

1 回答 1

4

这里应该没有问题。

FRIEND_TEST在这种情况下,只需定义

friend class FooTest_BarReturnsZeroOnNull_Test;

这是使用TEST宏最终定义的类。无需gtest 或您的任何测试代码链接到foo库/exe。你只需要#include "gtest/gtest_prod.h"像你所做的那样。

在 foo_test.cc 中,您需要这样做,因为它使用的是对象#include "foo.h"的实际实例。Foo您还需要将foo库链接到测试可执行文件,或者如果foo不是库,则需要在foo源代码中进行编译。

所以总而言之,foo除了微小的 gtest_prod.h 标头之外,不需要任何测试代码,但测试需要链接到foo代码。

于 2012-11-01T13:27:57.117 回答