2012-05-14 18 views
1

私のリポジトリを定義するデータアセンブリがあります。Moq、TDDおよび複数のレイヤー

私は自分のサービスを定義するサービスアセンブリを持っており、各サービスはNinjectによってコンストラクタに注入されたリポジトリを持っています。

私はユニット私のサービスメソッドをテストしていた場合、すべてが正常である:(別のレベルダウン)私のコントローラをテストするとき

[TestClass] 
public class UserTests 
{ 
    IQueryable<User> users; 
    int userID; 

    public UserTests() 
    { 
     users = new List<User>() 
     { 
      new User { EmailAddress = "[email protected]", Password = "password", ID = 1} 
     }.AsQueryable(); 
    } 

    [TestMethod] 
    public void Known_User_Can_Login() 
    { 
     // Arrange 
     var repository = new Mock<IUserRepository>(); 
     var service = new UserService(repository.Object); 

     repository.Setup(r => r.GetAll()) 
      .Returns(users); 

     // Act 
     bool loggedIn = service.UserLogin("[email protected]", "password", out userID); 

     // Assert 
     Assert.IsTrue(loggedIn); 
     Assert.AreEqual(1, userID); 
    } 

    [TestMethod] 
    public void Unknown_User_Cannot_Login() 
    { 
     // Arrange 
     var repository = new Mock<IUserRepository>(); 
     var service = new UserService(repository.Object); 

     repository.Setup(r => r.GetAll()) 
      .Returns(users); 

     // Act 
     bool loggedIn = service.UserLogin("[email protected]", "password", out userID); 

     // 
     Assert.IsFalse(loggedIn); 
    } 
} 

しかし、私は問題に実行していますよ。

私のコントローラはサービスに依存しており、サービスはリポジトリによって異なります。私は私のコントローラテストを動作させるように見えません。ここでは、私がこれまで持っているものです。

[TestClass] 
public class AccountTests 
{ 
    IQueryable<User> users; 

    public AccountTests() 
    { 
     users = new List<User>() 
     { 
      new User { CompanyId = 1, EmailAddress = "[email protected]", Password = "password"}, 
      new User { CompanyId = 1, EmailAddress = "[email protected]", Password = "password"} 
     }.AsQueryable(); 
    } 

    [TestMethod] 
    public void Known_User_Can_Login() 
    { 
     int userID = 0; 

     var repo = new Mock<IUserRepository>(); 

     // Arrange 
     var service = new Mock<UserService>(repo.Object); 
     var controller = new AccountController(service.Object); 

     // Act 
     var result = controller.Login(new LoginModel { EmailAddress = "[email protected]", Password = "password" }) as RedirectToRouteResult; 

     // Assert 
     service.Verify(x => x.UserLogin("[email protected]", "password", out userID), Times.Once()); 
     Assert.AreEqual("Index", result.RouteValues["Action"]); 
    } 
} 

私は(私はそれにUserRepositoryのインスタンスを渡ししようとするんだけど、それが動作していない)UserServiceのをインスタンス化に関するエラーを取得しておきます。

私は何か愚かなことをする必要がありますが、何ですか?

+0

私はmoq/ninjectについてはわかりませんが、私はあなたのサービスを嘲笑しているので、これは決してリポジトリを必要としません。あなたの実際の実装は可能性があります。あなたはちょうど1つ下のレベルをテストする必要があります。あなたはあなたのSUTを持っていて、SUTがアクセスしようとしているオブジェクトだけをモックする必要があります。 –

+0

@Paul私はあなたのアプリに使用するコンポジションルートを見ることに興味があります。 –

答えて

2

のためのクラスで質問を更新してくださいUserServiceのインターフェイスであることを確認します。あなたはここでやっているよう。また、あなたはあなたの第二の試験でIUserRepositoryのインスタンスを

を作成しないする必要があります。

var repo = new Mock<IUserRepository>(); 
// Arrange 
var service = new Mock<UserService>(repo.Object); 

UserServiceのが嘲笑されているので、それはとにかくIUserRepositoryの呼び出しをすることはありません、あなたがドン」モックを作成するときに依存関係を提供する必要があります。

何をする必要が単にこのようUserServiceのためのモックを作成されています。でも、厳しいUserServiceのは、通常のリポジトリに依存してい

var service = new Mock<UserService>(); 

、部品番号はちょうど方法に缶詰の応答を提供し、したがって、しませんでしょう実際のリポジトリへの呼び出しを行う必要があります。

+0

ありがとう、優れた説明! – Paul

1

UserServiceクラス私は、インタフェースまたは抽象クラスではないと推測しています。そうでなければ、MockはUserServiceの実装を作成できないため、失敗するようになります。したがって、UserServiceのインタフェースを作成するか、抽象クラスとして定義するか、次のようにインスタンス化します。

var service = new UserService(repo.Object);

またはMock.Create<UserService>()を使用できますが、Mock.Provide<T>() apiを使用してすべての実装UserServiceニーズを提供する必要があります。

これが役に立ちます。

これで問題がイマイチ場合UserServiceのとリポジトリ

関連する問題