Refactor protected base class dependency for test

时间:2016-11-09 08:19:49

标签: c++ unit-testing refactoring

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.

2 个答案:

答案 0 :(得分:1)

你有模板方式:

Public Class CustomerDataService
    Implements LogicLayer.ICustomerDataService

    Public Sub New(context As DbContext)

    End Sub

    Public Function GetAll() As IEnumerable(Of Models.Customer)
        Return context.Customers
    End Function
End Class

答案 1 :(得分:0)

蛮力解决方案可能是: #define protected public

更清洁的机制是让UntouchableBase的测试朋友。这允许测试代码(以及测试代码)访问私有,受保护,同时保护它们免受其他一切的侵害。

应该做的是使用编译器定义进行单元测试:

#ifdef UNIT_TESTING
friend void UnitTestFn()
#endif

如果您使用的是Google Test,则可以使用FRIEND_TEST将您的测试文章声明为受测试类的朋友。