1

GoogleTestsでFRIEND_TESTがどのように機能するかを理解しようとしています。 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とBar()にアクセスするために、foo_test.ccにfoo.hが含まれている必要があるということです。[おそらく、Googleでは動作が異なりますか?私のコードには、それを含める必要があります]

その結果、循環依存になります...

私は何かが足りないのですか?

編集:コードサンプル:(修正後に再編集-テストファイルを*.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にある場合にのみ機能します)。privateprotectedに変更する必要がありますが、テストされたコード内で新しい宣言を行う必要はありません。

// 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

There shouldn't be a problem here.

FRIEND_TEST in this case simply defines

friend class FooTest_BarReturnsZeroOnNull_Test;

which is the class ultimately defined by using the TEST macro. There's no need to link gtest or any of your test code to the foo library/exe. You only need to #include "gtest/gtest_prod.h" as you have done.

In foo_test.cc, you need to #include "foo.h" since it's using an actual instance of a Foo object. You also need to link your foo library to the test executable, or if foo isn't a library, you need to compile in the foo sources.

So in summary, foo doesn't need any test code with the exception of the tiny gtest_prod.h header, but the test needs linked to the foo code.

于 2012-11-01T13:27:57.117 に答える