Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何让谷歌测试类与我的类成为朋友?_C++_Friend_Googletest - Fatal编程技术网

C++ 如何让谷歌测试类与我的类成为朋友?

C++ 如何让谷歌测试类与我的类成为朋友?,c++,friend,googletest,C++,Friend,Googletest,我听说有可能让google测试用例类朋友访问我的类,从而使测试能够访问我的私有/受保护的成员 如何做到这一点?试试这个(直接从谷歌测试文档…) 例如: // foo.h #include <gtest/gtest_prod.h> // Defines FRIEND_TEST. class Foo { ... private: FRIEND_TEST(FooTest, BarReturnsZeroOnNull); int Bar(void* x); }; // foo

我听说有可能让google测试用例类朋友访问我的类,从而使测试能够访问我的私有/受保护的成员

如何做到这一点?

试试这个(直接从谷歌测试文档…)

例如:

// 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.h
#包括
//定义友人测试。
福班{
...
私人:
FRIEND_测试(最足部,BarreturnszeronNull);
内部条形图(空心*x);
};
//foo_test.cc
...
测试(最足部,BarReturnsZeroOnNull){
富富,;
期望_EQ(0,foo.Bar(NULL));
//使用Foo的私有成员栏()。
}

我知道这很旧,但今天我在寻找相同的答案。“”只是引入了一个简单的宏来引用测试类

#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
So
FRIEND_测试(最足部,BarReturnsZeroOnNull)相当于:

friend class FooTest_BarReturnsZeroOnNull_Test;

这是有效的,因为每个测试都是它自己的类,如前一个答案所述。

更好的策略是不允许单元测试中的友元测试

允许好友测试访问私有成员将导致难以维护的代码库。在重构组件的内部实现细节时中断的测试不是您想要的。如果将额外的精力投入到可以通过组件的公共接口测试组件的设计中,那么您将得到只需要在组件的公共接口更新时更新的测试


依赖于
gtest/gtest_prod.h
的测试应被视为设计不良的标志。

当您的测试类和测试类位于不同的命名空间中(例如,您的测试位于全局命名空间中)时,您可能需要向前声明您的测试类,并在FRIEND_测试中添加命名空间前缀:

// foo.h
#include <gtest/gtest_prod.h>

class FooTest_BarReturnsZeroOnNull_Test;

// Defines FRIEND_TEST.
class my_namespace::Foo {
  ...
 private:
  FRIEND_TEST(::FooTest, BarReturnsZeroOnNull);
  int Bar(void* x);
};

// foo_test.cc
using namespace my_namespace;

...
TEST(FooTest, BarReturnsZeroOnNull) {
  Foo foo;
  EXPECT_EQ(0, foo.Bar(NULL));
  // Uses Foo's private member Bar().
}
//foo.h
#包括
类最足部试验;
//定义友人测试。
类my_命名空间::Foo{
...
私人:
FRIEND_测试(::FooTest,BarreturnsZeronNull);
内部条形图(空心*x);
};
//foo_test.cc
使用名称空间my_名称空间;
...
测试(最足部,BarReturnsZeroOnNull){
富富,;
期望_EQ(0,foo.Bar(NULL));
//使用Foo的私有成员栏()。
}

我知道朋友单元测试(或者C++中的友好性)和白盒测试是一个有争议的主题,但是当你在复杂的科学算法上工作时,你需要测试和验证的每一步,但是你不想公开(甚至是受保护的)接口,朋友测试在我看来是一个简单实用的解决方案,尤其是在测试驱动的开发方法中。如果使用友好性或白盒测试违背了一个人的宗教信仰,那么以后总是可以重构代码(或者完全删除白盒测试)。

如果我有另一个测试,比如BarreTurnsonOnSth,该怎么办。我是否也必须为该测试添加另一个FRIEND_测试声明?是的。从技术上讲,每个测试都是一个类,你需要一次和他们交一个朋友。我如何做才能不强迫我在类
Foo
的头文件中包含googletest头文件?@quant\u dev:请参阅Ralfizzle的答案,因为这样做时没有将其包含在gtest头文件中。请注意,测试类和待测试类必须位于同一命名空间中,如@DaveRuske中所述,请不要在编辑中解释您的编辑。这就是编辑摘要的目的。如果问题是6个字符的限制,你可以在身体的某个地方添加一个
是一个注释,因此不可见)。我理解这是有争议的(希望它为你赢得了某种“有争议的答案”徽章),但我很高兴有人提出了这个观点。很多人都同意@Martin的观点!这在一般情况下是正确的,但对于UI测试(考虑QT),您通常希望获得通常不会公开的子部件。例如,我需要检查当按下按钮时小部件是否可见。这个小部件通常不会公开。在开发测试策略时,会在各个方面进行权衡。您指出的优点是有效的,但这并不意味着使用
friend
进行测试总是一个坏主意。这个答案指出了其他答案遗漏的一件重要事情并拯救了我的世界:当使用friend类时,名称空间非常重要。
// foo.h
#include <gtest/gtest_prod.h>

class FooTest_BarReturnsZeroOnNull_Test;

// Defines FRIEND_TEST.
class my_namespace::Foo {
  ...
 private:
  FRIEND_TEST(::FooTest, BarReturnsZeroOnNull);
  int Bar(void* x);
};

// foo_test.cc
using namespace my_namespace;

...
TEST(FooTest, BarReturnsZeroOnNull) {
  Foo foo;
  EXPECT_EQ(0, foo.Bar(NULL));
  // Uses Foo's private member Bar().
}