Я пытаюсь понять, как работает 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();
}
Здесь не должно быть проблем.
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
код.
Других решений пока нет …