FRIEND_TEST в Google Test — возможна циклическая зависимость?

Я пытаюсь понять, как работает 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 (). [Возможно, это работает по-другому для 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, а не в заголовке); в то время как это требует изменения частный в защищенный, он не требует дополнительных объявлений внутри тестируемого кода, который каждый новый тест:

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

1

Решение

Здесь не должно быть проблем.

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 код.

4

Другие решения

Других решений пока нет …