在谷歌测试中访问受保护的变量

Accessing protected variable in googletest

本文关键字:受保护 变量 访问 谷歌 测试      更新时间:2023-10-16

我有这个类testC,用于谷歌测试

class testC : public A { };

然后是同一文件中的一堆 TEST。

TEST(test_case_name, test_name) {
 ... test body ...
}

A 的结构是这样的

class A{
protected:
   B b;
public:
   //constructors
   //destructor
   //member functions

问:如何通过testC访问所有TEST(){}功能中的b

我试图在testC做一个吸气剂

public:
  testC getTest(){
      testC test;
      return test;
  }

我也尝试返回参考,但没有运气......

试试googletest提供的FRIEND_TEST宏。请查看私有课程成员下的高级指南。

您必须将测试声明为被测试代码的好友。如果我没记错的话,您必须为所有想要访问受保护成员的测试声明友谊。

class MySystemUnderTest
{
    #ifdef _MY_UNIT_TEST
    FRIEND_TEST(MySystemUnderTest_test, functionA_prereq_expected);
    FRIEND_TEST(MySystemUnderTest_test, functionB_prereq_expected);
    #endif
    ...
};

在上面的示例中,我使用预处理器符号_MY_UNIT_TEST从生产代码中删除声明。方法functionA_prereq_expectedfunctionB_prereq_expected将在测试夹具MySystemUnderTest_test中定义。

您必须在测试的代码中添加 FRIEND_TEST 声明。如果您想针对受保护/私人成员进行测试,这就是您必须付出的代价。

不是将

FRIEND_TEST直接添加到要测试的类中ClassToTest并被protected成员和方法的#ifdef语句(如 anhoppe 的帖子所建议的那样(包围,而是创建另一个类test::ClassToTest,它继承自要测试的类,并将测试套件和测试注册为朋友,如下所示:

内部文件implementation.hpp

namespace some {
  namespace complicated {
    namespace ns {
      // Class that we want to test
      class ClassToTest {
        public:
          constexpr ClassToTest() noexcept
            : member_to_be_accessed{7} {
            return;
          }
        protected:
          // The protected member (or method) to be accessed
          int member_to_be_accessed;
      };
    }
  }
}

文件内部test.hpp

#include <gtest/gtest.h>
#include "implementation.hpp"

namespace test {
  // The derived class that registers the test fixture and tests as friends
  class ClassToTest : public some::complicated::ns::ClassToTest {
    using some::complicated::ns::ClassToTest::ClassToTest;
    friend class SomeTestFixture;
    FRIEND_TEST(SomeTestFixture, someTest);
  };
  // The test fixture
  class SomeTestFixture : public testing::Test {
    protected:
      SomeTestFixture() noexcept 
        : class_to_test{} {
        return;
      }
      ClassToTest class_to_test;
  };
  // A test
  TEST_F(SomeTestFixture, someTest) {
    EXPECT_EQ(class_to_test.member_to_be_accessed, 7);
  }
}

这样做的好处是,你可以清楚地将测试与实现分开,并且可以绕过有关命名空间的限制

如果类是在命名空间中定义的,那么为了成为朋友类别、测试夹具和测试的定义必须完全相同命名空间,不带内联或匿名命名空间。

<小时 />

此外,正如">高级GoogleTest指南"的"测试私有代码"部分所指出的,通常应该使用黑盒方法:代码应该只通过其公共接口进行测试。如果可以,请使用实现指针 (PImpl( 设计策略重新构建将接口与实现分开的代码,并独立测试内部结构。