Rhino Mocks -Stub A Singleton
-
12-09-2019 - |
質問
このような静的プロパティを介してクラスにアクセスされるシングルトンがあります。OtherClassNotBeingTested.Instance.SomeInstanceMethod()
これらのオブジェクトの1つを作成することなく、クラスをテストしたいと思います。静的プロパティのゲッターがスタブを返す方法はありますか Instance
呼ばれていますか?
より明確にするために、インスタンスプロパティのコードは次のとおりです。
/// <summary>
/// Make a property to allow the OtherClassNotBeingTested class
/// to be a singleton
/// </summary>
public static OtherClassNotBeingTested Instance
{
get
{
// Check that the instance is null
// NOTE: COMMENTS BELOW HAVE SHOWN THIS TO BE BAD CODE. DO NOT COPY
if (mInstance == null)
{
// Lock the object
lock (mSyncRoot)
{
// Check to make sure its null
if (mInstance == null)
{
mInstance = new OtherClassNotBeingTested();
}
}
}
// Return the non-null instance of Singleton
return mInstance;
}
}
更新:これが私がそれを修正する方法です:
class ClassBeingTested
{
public ClassBeingTested(IGuiInterface iGui):this(iGui, Control.Instance)
{
}
public ClassBeingTested(IGuiInterface iGui, IControl control)
{
mControl = control;
//Real Constructor here
}
}
私のユニットテストは、2番目のコンストラクターを呼び出します。実際のコードは、最初のコンストラクターを呼び出します。クラスのコードはローカルフィールドを使用します マコントロール シングルトンの代わりに。 (これは依存噴射と呼ばれていると思います。)
また、シングルトンをリファクタリングしました トニー・ザ・ポニーの提案。
解決
私はあなたのことを願っています mInstance
変数は揮発性と宣言されています。そうしないと、DCLの実装が壊れています。真剣に、あなたは本当にそのレベルの怠inessが必要ですか?私は個人的にいくつかをお勧めします よりシンプルなパターンが利用可能です.
ただし、モッキングに関しては、いいえ、Rhinomocksで静的コールを模倣することはできません。これを許可するツールがいくつかあります。 TypeMock, 、しかし、個人的には、そもそもアプリをよりテストしやすくするようにリファクタリングします。
別のオプションは、テストケースでシングルトンプロパティの価値を設定できる「不正行為」シングルトンを持つことです。プロパティにシングルトンクラス自体の代わりにインターフェイスを返す場合は、実際のシングルトンを模擬に置き換えることができます。
他のヒント
他の噂にもかかわらず、あなたはシングルトンをock笑することができます、私の答えを参照してください:
この場合、静的コンストラクターがないため、さらに簡単です。シングルトンがすでにインターフェイスを実装している場合、生産的なコードを変更する必要はありません。