2016-11-09 9 views
1

この問題は、「基底クラスで保護されたインターフェイスを提供する」パターンを非常に頻繁に使用する現実のプロジェクトから発生します。私はGetValueメソッドの依存関係を置き換えるために、高速で、大部分は非侵襲的なリファクタリングを探していますテスト用のリファクタリング保護された基底クラスの依存性

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

:ここ

は小さな例です。 の抽出方法と新しいクラスを追加はHeavyWeightClassIWantToTest

@UPDATEのために許可されている:テスト、問題

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

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

ヒント説明する:現在、我々はテスト目的のためにUntouchableBase実装を置き換えるために、リンカシームを使用していることを。

コード例を示してください。

+0

'UntouchableBase'どのようアンタッチャブルです: –

+0

UntouchableBaseでの変更は非常に高いコストで行われます。 GetValue()メソッドは仮想ではないので、直接オーバーロードすることはできません。 – mrAtari

+0

"オーバーロード"ではなく "オーバーライド"を意味すると思いますが、誰も 'pUntouchableBase-> GetValue()'を実行していないと指定した場合、中間クラスのバージョンで関数を非表示にできます。 –

答えて

0

ブルートフォースソリューションは次のようになります。 #define protected public

よりクリーンなメカニズムはUntouchableBaseのテストの友人を作ることです。これにより、テストコード(およびテストコードだけ)がprivates、protectedsにアクセスし、他のすべてのものからそれらを保護することができます。 1は何をすべき

は、コンパイラを使用しているユニットテストのために定義します。

#ifdef UNIT_TESTING 
friend void UnitTestFn() 
#endif 

は、Googleのテストを使用している場合は、テスト対象のクラスに友人としてあなたのテストfixtueを宣言するFRIEND_TESTを使用することができます。

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

全く助けにならない。 GetValue呼び出しを置き換える方法は? – mrAtari

1

あなたは、テンプレートの方法がありますか?ヘッダーファイルを修正することはできますか? `class TestableBase:public UntouchableBase`はどうでしょうか?そして` TestableBase`から `HeavyWeightClass`を派生させますか?
+0

+1の 'this->'オーバーロード!残念ながら、生産コードでのHeavyWeightClassの作成はシステムによって行われます。また、多くのHeavyWeightクラスがあり、すべて同じ方法で処理されます。 – mrAtari

関連する問題