You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已声明友元类,仍无法在Google Test TEST_F函数中设置私有成员

问题:TEST_F函数无法访问类私有成员,SetUp()却可以?

我在SetUp()方法里能成功设置并访问privateData,但在TEST_F函数里做同样操作时,代码编译失败,提示函数不可访问。我本来以为通过友元类声明应该允许这种操作,但显然哪里出问题了——是测试fixture配置错了,还是我对C++友元机制理解有误?

相关代码

A.h

#ifndef A_H
#define A_H

class A {
    friend class testsA;  // Friend class declaration

private:
    int privateData;

public:
    A() : privateData(0) {}
private:
    void setPrivateData(int data) { privateData = data; }
    int getPrivateData() const { return privateData; }
};

#endif // A_H

testsA.h

#ifndef TESTS_A_H
#define TESTS_A_H

#include "A.h"
#include <gtest/gtest.h>

class testsA : public testing::Test {
public:
    A* a_instance;  // Public member instance of A
    
protected:
    void SetUp() override {
        a_instance = new A();
        a_instance->setPrivateData(42);  // Set private member in SetUp
    }
};

#endif // TESTS_A_H

测试实现文件

#include "testsA.h"

TEST_F(testsA, TestPrivateDataSetting) {
    // Trying to access and set private data in the test case
    a_instance->setPrivateData(100);
    ASSERT_EQ(a_instance->getPrivateData(), 100);
}

TEST_F(testsA, EnsureSetUpValueAccessible) {
    // This will access the value set in SetUp
    ASSERT_EQ(a_instance->getPrivateData(), 42);
}
原因与解决方法

问题核心是Google Test的TEST_F宏会生成一个继承自你的testsA类的新测试类,而你给A声明的友元仅仅是testsA本身,它的子类(也就是TEST_F生成的类)不在友元列表里,自然无法访问A的私有成员。

而SetUp()是testsA类的成员函数,属于友元类的成员,所以能正常访问A的私有内容。

给你两种可行的解决办法:

方法1:修改友元声明适配GTest的模板机制

把A类里的友元声明改成允许所有testing::Test的子类访问,也就是用模板友元:

class A {
    // 替换原来的friend class testsA;
    template <typename T>
    friend class testing::Test;
private:
    // ... 原有代码不变
};

这样所有基于GTest Test类的测试子类,包括TEST_F生成的类,都能访问A的私有成员了。

方法2:在Fixture中封装私有成员访问接口

不在测试用例里直接操作A的私有方法,而是在testsA类里封装一层公共接口,测试用例调用这些接口即可:
修改testsA.h:

class testsA : public testing::Test {
public:
    A* a_instance;
    
    // 封装访问A私有成员的接口
    void setAPrivateData(int data) {
        a_instance->setPrivateData(data);
    }
    
    int getAPrivateData() const {
        return a_instance->getPrivateData();
    }
    
protected:
    void SetUp() override {
        a_instance = new A();
        setAPrivateData(42);
    }
};

然后修改测试用例:

TEST_F(testsA, TestPrivateDataSetting) {
    setAPrivateData(100);
    ASSERT_EQ(getAPrivateData(), 100);
}

TEST_F(testsA, EnsureSetUpValueAccessible) {
    ASSERT_EQ(getAPrivateData(), 42);
}

这种方法更符合封装原则,也不用修改被测试类A的友元声明。

内容的提问来源于stack exchange,提问作者Sam12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:50:17