使用googletest测试受保护成员

10

在使用Google测试时,我对继承方面感到困惑。我有一个class A,其中包含protected属性。如果我想要访问这些属性,我必须扩展该类,但同时我还需要扩展public ::testing::Test,仅为了使用gtest

最优雅的解决方案是什么? 另外,我正在尝试避免使用#define protected public

4个回答

25

为了避免在被测试的类中留下测试痕迹,请使用带有夹具的多重继承:

class ToBeTested
{
protected:
    bool SensitiveInternal(int p1, int p2); // Still needs testing
}

// Google-test:
class ToBeTestedFixture : public ToBeTested, public testing::Test
{
   // Empty - bridge to protected members for unit-testing
}

TEST_F(ToBeTestedFixture, TestSensitive)
{
    ASSERT_TRUE(SensitiveInternal(1, 1));
    ASSERT_FALSE(SensitiveInternal(-1, -1));
}

1
因为这似乎只在ToBeTested仅具有无参数构造函数时才起作用,所以我在这里卡住了。在我的情况下,我有一个带有参数的构造函数。 - gregb212

5

有一个FRIEND_TEST的声明,它在被测试类的头文件中使用。基本上它将测试定义为类的友元。在我的用例中,当以RELEASE模式编译时,我们禁用所有测试包含,因此它不会对真正的可执行文件造成任何伤害。

请参考这里


正是我所需要的,谢谢 :) - jabk
总是乐意帮忙 :) - lisu
文档链接已移至此处:https://github.com/google/googletest/blob/master/googletest/docs/advanced.md - Richard
新位置在这里 - Louis Go

0
我最终采用了Rene'slisu's的答案的组合来解决非默认构造函数的问题。
class ToBeTested
{
public:
    ToBeTested() = delete;

    ToBeTested(int p): p1(p) {}

protected:
    bool SensitiveInternal(int p2) {return p1 == p2;}// Still needs testing

    const int p1;
};

// Stub to bridge the acess restrictions:
class ToBeTestedStub : public ToBeTested
{
public:
    ToBeTestedStub(int p):ToBeTested(p) {}
    FRIEND_TEST(ToBeTestedFixture, TestSensitive);
};


// Google-test:
class ToBeTestedFixture : public testing::Test
{
public:
    void SetUp() override
    {
        stub = std::make_unique<ToBeTestedStub>(1);
    }

    // Using a pointer so we can instantiate the stub in the SetUp method.
    std::unique_ptr<ToBeTestedStub> stub;
};

TEST_F(ToBeTestedFixture, TestSensitive)
{
    ASSERT_TRUE(stub->SensitiveInternal(1));
    ASSERT_FALSE(stub->SensitiveInternal(2));
}

这里展示了一个替代方案:这个答案

// Stub to bridge the acess restrictions:
class ToBeTestedStub : public ToBeTested
{
public:
    ToBeTestedStub(int p):ToBeTested(p) {}
    using ToBeTested::SensitiveInternal;
};

0
我建议实现一个继承基类A的桩类B。 类B将基类A的所有受保护方法公开化。 这样,您可以实例化一个桩对象并像往常一样进行测试。
class Base
{
 public:
  Base(int x);
  virtual ~Base()=default;
 
 protected:
  bool myMethod();
}

class stubBase : public Base
{
 public:
  stubBase(int x) : Base(x){}
  bool myMethod(){ Base::myMethod(); }
}

TEST(Base, myMethod)
{
  stubBase stub(1);
  EXPECT_TRUE(stub.myMethod());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接