Reputation: 1458
I'm confused regarding inheritance when googletesting. I have a class A
that has protected
attributes. If I want to access those i have to extend that class, but at the same time i also need to extend public ::testing::Test
for the sole purpose of gtest
.
What is the most elegant solution to this problem?
Also I'm trying to avoid #define protected public
Upvotes: 10
Views: 15051
Reputation: 1891
I ended up using a combination of Rene's and lisu's answers to solve the problem of non-default constructors:
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));
}
An alternative is shown in this answer:
// Stub to bridge the acess restrictions:
class ToBeTestedStub : public ToBeTested
{
public:
ToBeTestedStub(int p):ToBeTested(p) {}
using ToBeTested::SensitiveInternal;
};
Upvotes: 1
Reputation: 184
I suggest to implement a stub class B which inherits the base class A. Class B then provides all the protected methods of class A as public. That way you can instanciate a object of the stub object and take it under test as usual.
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());
}
Upvotes: 0
Reputation: 2263
There is a FRIEND_TEST declaration, which is used in the header of tested class. Basically it defines the test as a friend of the class. In my use case, we disable all test includes when compiling in RELEASE mode, so it doesn't do any harm the real executable.
Have a look at this
Upvotes: 6
Reputation: 261
To avoid leaving traces of tests in the tested class use multiple-inheritance with a fixture:
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));
}
Upvotes: 26