2009-09-17 8 views
6

テストケースを構築できるように、依存関係注入パターンを使用してDefaultControllerという名前のMVCベースコントローラを実装しました。以下の例:テスト目的のための基本コントローラ依存性注入を解決するには?

public class DefaultController : Controller 
{ 
    protected readonly ISessionHelper _sessionHelper; 
    string _thisUserOpenID; 
    protected IUsersRepository _UserRepository; 
... 
    public DefaultController() 
    { } //not for testing 

    public DefaultController(ISessionHelper session, IUserRepository repo) 
    { 
     _sessionHelper=session; 
     _UserRepository = repo; 
    } 
} 

その後、私は私がどのように実際に知っていない状況で自分自身を発見したいくつかのテストケースを構築し、今

など、このコントローラ、にHomeController、UserControllerでを使用して、私のコントローラを持っています注入依存パターンを使用します。

[TestMethod] 
    public void Welcome_Message_In_ViewData_Has_Coockie_User_Display_Name() 
    { 
     // Below I want to insert FakeRepositories using 
     //ISessionHelper and so on. but the constructor 
     //for homecontroller don't have it. 
     HomeController controller = new HomeController(); 

答えて

5

HomeControllerには、 "注入可能な"コンストラクタが必要です。このコンストラクタは、ベースコンストラクタを呼び出します。

public HomeController(ISessionHelper session, IUserRepository repo) 
    : base(session, repo) 
    { 

    } 

ここで、テストでは、そのコンストラクタを使用してHomeControllerを作成し、セッションとユーザーリポジトリをモックアップして渡します。模倣について言えば、多くの人気模擬フレームワークのコードでScott Hanselman's MvcMockHelpers classesに興味があるかもしれません。

3

コンストラクタが2つある理由はわかりません。あなたは1つだけ持っている必要があります、パラメータなしでコンストラクタを取り除く。キャッスルウィンザーのようなDIフレームワークを使用して、私の好みのもの、オートファックはあなたのためにこれすべてを処理します。それでは、テストではMoqのようなものを使用しています。 DIフレームワークでDefaultController、ISessionHelper、IUserRepositoryを登録します。DIフレームワークでDefaultController、ISessionHelper、IUserRepositoryを登録します。線に沿って何か:

Register(new DefaultController()); (it is something like that in Autofac) 
Register<SessionHelper>().As<ISessionHelper>(); 
Register<UserRepository>().As<IUserRepository>(); 

そのように、あなたはコンテナからDefaultControllerを引くことができますし、DIフレームワークでは、あなたのための2つのパラメータを注入します。

var controller = IoC.Resolve<DefaultController>(); 

基本的Autofacにオーバー頭や顔をしている:私はそれのように見える、私のDIコンテナにアクセスするための静的メソッドを包みます。あなたのためにあなたのコントローラを登録するためのWebモジュールもあります。

次に、テストのためにMoqを使用するか、「AutoMocker」(google it)の何らかの形を見つけてください。私はそうするでしょう:

var session = new Mock<ISessionHelper>(); 
var repo = new Mock<IUserRepository>(); 
repo.Setup(s => s.FindById(123)).Returns(new User()); 

var conroller = new DefaultController(session.Object, repo.Object); 
controller.Execute(); 

またewwwリポジトリ。 .Netとジェネリックスなどで...ちょうどあなた自身が素晴らしいセッションを作成します。

var session = IoC.Resolve<ISession>(); 
var user1 = session.Get<User>(123); 
var user2 = session.Get<User>(u => u.Username == "admin"); 
session.Update(user3); 

これは、1つのことを渡すだけで、何でも使用できます。時には多くのリポジトリを渡す必要はありません。また、Unit Of Workパターンにもうってつけです。

+0

ちょっと注意してください。パラメータのないコンストラクタを取り除くと、独自のコントローラファクトリをロールバックする必要があります。 – womp

+0

なぜ工場ですか?上のケースでは、DIフレームワークがすべてを注入しています。 ISessionHelperやIUserRepositoryのようなものは、静的セッションを実行する必要があります。ほとんどの場合、渡す値はありません。 あなたがする必要があるのは、 です。var controller = IoC.Resolve ;それはすべてあなたのために構築されています。 コンストラクタを介して注入することは、viaメソッドのparamsに変数を渡すか、publicプロパティを設定する(コマンドパターンと同じように)ことを意味します。 – Bealer

関連する問題