Reputation: 650
This problem comes from a real world project, which uses the "provide protected interface in base class" pattern very often.
Here's a small example:
class UntouchableBase
{
protected: //cannot be called from outer class
int GetValue() { return 42;}//not virtual
//this class has many many more "protected interface" methods
};
class HeavyWeightClassIWantToTest: public UntouchableBase
{
public:
// VeryHeavyClassIWantToTest(...) {} //ignore the creation issue for a heavy weight object here
void MethodThatNeedsTest()
{
//calc some values
int result = GetValue();
//do some other stuff
}
};
I'm looking for a fast, mostly noninvasive refactoring, to replace the GetValue dependency.
Extracting Methods and adding new class is allowed for HeavyWeightClassIWantToTest
@UPDATE: Test,to illustrate the issue
TEST(EnsureThat_MyMethodThatNeedsTestDoesSthSpecial)
{
HeavyWeightClassIWantToTest sut = MakeSut();
sut.MethodThatNeedsTest(); //should call a mocked / replaced GetValue()
}
Hint: Currently we're using a linker seam to replace the UntouchableBase
implementation for testing purposes.
Please provide coded examples.
Upvotes: 1
Views: 60
Reputation: 217950
You have the template way:
template <typename Base>
class HeavyWeightClassIWantToTestGeneric: public Base
{
public:
// ...
void MethodThatNeedsTest()
{
//calc some values
int result = this->GetValue(); // use `this->` for dependent name
//do some other stuff
}
};
// For production
using HeavyWeightClassProduction = HeavyWeightClassIWantToTestGeneric<UntouchableBase>;
// For Test
using HeavyWeightTest = HeavyWeightClassIWantToTestGeneric<TestBase>;
Upvotes: 1
Reputation: 1489
The brute-force solution could be:
#define protected public
More cleaner mechanism is to make the test friend of the UntouchableBase
. This allows the test code (and just the test code) access to the privates, protecteds, whilst protecting them from everything else.
What one should do is use a compiler define for unit testing:
#ifdef UNIT_TESTING
friend void UnitTestFn()
#endif
If you are using Google Test, you can use FRIEND_TEST to declare your test fixtue as a friend to the class under test.
Upvotes: 0