問題
単体テストを書くとき、モック オブジェクトが必要になることがよくあります。製品オブジェクトを置き換え可能にするために、モック オブジェクト クラスは製品オブジェクト クラスから派生し、いくつかの仮想関数をオーバーライドします。
本番クラスに仮想機能がなく、それを変更する権限がない場合に問題が発生します。今のところ、問題を解決するための 2 つの選択肢があります。
クラスを、サブシステム タイプによってパラメーター化されたクラス テンプレートに変換します。あなたの生産クラスは
、テストのために使用されますMyClass<ProductionSubsystem>
MyClass<MockSubsystem>
ラップされたサブシステム クラスの非仮想関数を呼び出す仮想関数を含むラッパーを手動で記述します。次に、ラッパーをモックします。
2つのオプションのいずれにも完全に満足しているわけではありません. 1 は「単純な」クラスをクラス テンプレートに変換することを強制し、2 は多くのボイラー プレート コードを記述することを強制します。
そのため、非仮想クラスのラッパーを作成するプロセスを自動化できるかどうか疑問に思っていました。私は次のようなものを想像します:
// The subsystem that contains the production code
class Interface
{
void nonVirtualFunction();
}
// Contains the same functions as Interface but does not derive from it
class Implementation
{
void nonVirtualFunction();
};
// wrapper base class that provides the virtual interface
template<typename Interface>
class AutoWrapper
{
// Do some magic to provide the same functions that Interface has, but virtual.
}
// Class to provide the interface of AutoWrapper<Interface> but calls the functions in Implentation.
template<typename Implementation, template Interface>
class AutoWrapperImpl
{
// do some other magic here ...
};
このセットアップでは、次のユース ケースが可能になります。
// code using the AutoWrapper
void useAutoWrapper()
{
AutoWrapper<Interface> wrapper = new AutoWrapper<Interface>();
wrapper->nonVirtualFunction(); // calls Interface::nonVirtualFunction()
wrapper = new AutoWrapperImpl<Interface,Implementation>();
wrapper->nonVirtualFunction(); // calls Implementaion::nonVirtualFunction()
}
質問
C++ で AutoWrapper と AutoWrapperImpl の 2 つのクラスを実装することは可能ですか? もしそうなら、それはどのように行われ、公開されている解決策はありますか?