2011-12-10 9 views
2

タイトルほとんど私が求めていることを言いますが、私はちょうど私が何をしているのか説明します。テスト中にモックを返し、通常の実行中に実際の実装を返すクラスインスタンス

最近私は単体テストを読んできましたが、私は頭をモックの周りに巻くのに問題があります。特にシステム/システムのリソースに関係するオブジェクトの模倣。

ネットワークと対話する必要のあるクラスがあるとします。

.NET内のユニットテストで読んだことは、基本的に、ネットワークとやり取りするクラスの周りにラッパーオブジェクトを作成することです。そして、そのオブジェクトのインターフェースを(例えばコンストラクターを介して)ロジッククラスに渡します。テストの際には、そのラッパークラスを模擬のものに置き換えることができます。

時には、クラスはコンストラクタまたはセッタ関数を介して奇妙なアダプタやラッパーを受け入れたり受け入れたりしないように、基本的に十分です。

基本的には、単体テストを達成するために、それぞれのクラスに依存するクラスを受け入れることで、コードが複雑になります。

私の質問は単純ですが、オブジェクトのインスタンス作成中に実際のものが返されるような仕組みがありますか(通常の実行であればモック1、テストであればモック1)。

答えて

3

多くのファイルシステム操作を行うクラスがあり、実際のファイルシステムへのファイルの読み書きを心配せずにクラスをテストできるようにしたいとします。

public interface IFileSystem 
{ 
    bool FileExists(string filePath); 
    string[] ReadAllLines(string filePath); 
    //...more methods as appropriate 
} 

をし、ラッパークラスのインターフェイスを実装:

あなたは以下に似たインターフェースを作成、ファイルシステムの操作クラスで、その後

public class RealFileSystem : IFileSystem 
{ 
    public bool FileExists(string filePath) 
    { 
     return File.Exists(filePath); 
    } 

    public string[] ReadAllLines(string filePath) 
    { 
     return File.ReadAllLines(filePath); 
    } 
} 

を、あなたはそれをインスタンス化したいです依存性注入を使用して

ご覧のとおり、上記のクラスには2つのコンストラクタがあります:1つはIFileSystemを実装するクラスのインスタンスを取り、もう1つはIFileSystemを実装します。 1つのクラスを呼び出さないクラスは、クラスの存続期間中に新しいRealFileSystemをインスタンス化します。

次に、ユニットテストのために、そのクラスにIFileSystemのモックを注入できます。あなたはRhinoMocksまたは部品番号のようなモックフレームワークを使用することができ、またはあなたは自分自身をロールバックすることができます:

public class FakeFileSystem : IFileSystem 
{ 
    public bool FileExists(string filePath) 
    { 
     return true; 
    } 

    public string[] ReadAllLines(string filePath) 
    { 
     return new[] {"This", "is", "a", "bunch of", "text!"}; 
    } 
} 

そして、あなたのテスト中に、実現する

var objectToTest = new ClassThatDoesFileSystemStuff(new FakeFileSystem()); 

重要なことは、あなたが緩くしているということですかあなたのクラスを結合する。 は、使用するIFileSystemのタイプを知るクラスではありません。 に、に、使用するIFileSystemの実装を教えてほしい。

+1

+1良い例です!私の唯一の疑問は、2つのコンストラクタとの違いです.Poor Man's DIではなくDI Containerフレームワークを使用します。私はあなたがその例を複雑にしたくないと思っています。 – TrueWill

+0

@TrueWill正解!私はいくつかのNinjectを愛しています:) –

+0

@トルー私はいくつかの貧しい人のDIを愛しています。 :-) Ninjectは優れたDIコンテナの1つですが、本当に必要なのかどうか疑問に思うこともあります。 – bcarlso

1

あなたの最初の説明は正しいです。あなたは正しい道を歩いています。

通常、クラスがだからベーシックなので、依存関係は必要ありません(それはおそらくあなたが考えるよりも基本的です)。テストする価値のある振る舞いはありません。それはアダプタです - あなたはそれをオフにして、他のものへの依存としてそれを注入します。

あなたは確かにすることができます。は特定の状態のクラスから偽の実装を返しますが、それほど問題になる場合は、2つの実装、インターフェイス、およびコンストラクタパラメータを持つ方が簡単でしょう。

いずれにしても、私はプロダクションコードでモックライブラリ(AKA分離フレームワーク)を参照しないようにしています。私はそれらをテストコードで参照するだけです。テストクラス以外のクラスから偽物を返す場合は、実装を記述します。

関連する問題