2016-11-09 47 views
1

此問題來自一個真實世界的項目,該項目使用「經常在基類中提供受保護的接口」模式。重構受保護的基類依賴項測試

這裏有一個小例子:

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 
    } 
}; 

我在尋找一種快速,無創大多重構,以取代的GetValue依賴。 提取方法和添加新的類允許HeavyWeightClassIWantToTest

@UPDATE:測試,來說明這個問題

TEST(EnsureThat_MyMethodThatNeedsTestDoesSthSpecial) 
{ 
    HeavyWeightClassIWantToTest sut = MakeSut(); 

    sut.MethodThatNeedsTest(); //should call a mocked/replaced GetValue() 
} 

提示:目前,我們正在使用的接頭縫更換UntouchableBase執行用於測試目的。

請提供編碼示例。

+0

老虎屁股摸不得是'UntouchableBase'?你可以修改頭文件,甚至沒有?那麼'class TestableBase:public UntouchableBase',然後從'TestableBase'派生'HeavyWeightClass'? –

+0

UntouchableBase的變化成本非常高。您不能直接重載,因爲GetValue()方法不是虛擬的。 – mrAtari

+0

我認爲你的意思是「重寫」而不是「重載」,但是假如沒有人在做'pUntouchableBase-> GetValue()',你可以用中間類中的版本來隱藏函數。 –

回答

0

蠻力的解決辦法是: #define protected public

更清潔機制,是使UntouchableBase的考驗的朋友。這允許測試代碼(以及測試代碼)訪問私有,受保護的,同時保護它們免受其他一切的影響。

什麼人應該做的是使用編譯器定義單元測試:

#ifdef UNIT_TESTING 
friend void UnitTestFn() 
#endif 

如果您使用的是谷歌測試,你可以使用FRIEND_TEST申報測試fixtue作爲測試的朋友可以關注類。

+0

根本沒有幫助。如何替換GetValue調用? – mrAtari

1

你有模板的方法:

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>; 
+0

+1'this->'overload!不幸的是,在生產代碼中創建HeavyWeightClass是由系統完成的。許多HeavyWeight類都以相同的方式處理。 – mrAtari