我想弄清楚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):
Project ppppp - file 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();
};
Project ppppp_gtest,file 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();
}
答案 0 :(得分: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
代码相关联。