如何在gtest中使用带有命名空间的友元类

How to use friend class with namespace in gtest

本文关键字:命名空间 友元 gtest      更新时间:2023-10-16

假设我的Add.h在一个命名空间中,并且我让它成为AddTest的朋友,这样它就可以访问AddTwoNumber。

namespace mynamespace
{
class Add
{
 friend class AddTest;
 public:
  Add(){};
  ~Add(){};
 private:
  int AddTwoNumber(const int a, const int b){return a+b};
};
}

我的AddTest.h是

#include "Add.h"
#include "gtest/gtest.h"
class AddTest : public ::testing::Test
{
 protected:
  AddTest(){};
  virtual ~AddTest(){};
  virtual void SetUp()
  {
    mynamespace::Add addobj;
    result = addobj.AddTwoNumber(2, 3);
  };
  virtual void TearDown(){};
  int result;
};

然而,返回的错误是AddTwoNumber是私有的。如果我在Add.h中去掉"mynamespace",代码就会工作。有没有一种方法可以保留名称空间,同时仍然允许AddTest访问Add.h中的私有方法?

使用将AddTest限定在全局命名空间中

friend class ::AddTest;

如果没有::,它将声明nynamespace::AddTest为朋友。

测试代码永远不应该出现在生产代码的声明中。换句话说,如果AddTwoNumber需要测试,那么它的行为应该是可测试的,并且可以通过类Add的公共成员进行观察。如果没有人能从Add类的可调用接口观察到AddTwoNumber的结果,那么它怎么能做任何有用的事情呢?

当您首先编写代码测试时,您最终得到的生产代码会自然地遵循这个组织。当你在之后编写测试时,你最终会遇到你所描述的情况,你想测试的东西就埋在里面。这就是遗留代码(没有测试的代码)的情况。当您在编写测试之前编写实现时,您正在创建遗留代码。

有关使用遗留代码的更多详细信息,请参阅Michael Feathers的著作《有效使用遗留代码》。他描述了许多解耦代码的技术,这样您就可以在不必要地污染公共声明的情况下对其进行测试。

立即查看我的C++!2014年C++测试驱动开发研讨会,介绍使用Boost.Test进行C++测试驱动的开发。研讨会包括演示中每个步骤的代码,因此您可以直接在计算机上进行演示。

Jeff Langr的书《现代C++编程与测试驱动开发》是对使用现代C++进行测试驱动开发的极好论述。Jeff的书中有一个参考书目,引用了对实证研究的研究,显示了测试驱动开发的好处。