2017-05-02 17 views
1

警告を使用した三つの依存関係を持つMVCコントローラにどのように:私は、一般的に、部品番号、部品番号とユニットテスト、およびTDDに新しい尻のブランドです。ユニットテスト部品番号

私は3つの依存関係を持つコントローラを持っています。ここでは、今

public class SomethingController : Controller 
    { 
     private readonly ILogger<SomethingController> _logger; 
     private readonly ISomethingRepository _something; 
     private readonly IExceptionSvc _ex; 

     public SomethingController(ILogger<SomethingController> logger, 
      ISomethingRepository something, 
      IExceptionSvc ex) 
     {    
      _logger = logger; 
      _something = something; 
      _ex = ex; 

     } 

[HttpGet] 
     [AllowAnonymous] 
     public JsonResult GetStuff() 
     { 
      //intitialize list 
      var stuffs = new List<StuffViewModel>(); 

     try 
     { 
      _logger.LogInformation("SomethingController: GetStuff() - Getting Stuff, sorted ascending."); 

      //get the stuffs 
      stuffs = _something.GetStuff(); 

      _logger.LogInformation("Retrieved {0} Stuffs.", stuffs.Count); 
     } 
     catch (Exception ex) 
     { 
      _logger.LogError("Error in SomethingController: GetStuff()", ex); 
      return _ex.Http500ErrorReturn("GetStuff"); 
     } 

     return Json(stuffs); 
    } 

} 

各依存関係が何のためにあるのかの説明である:ここでSomethingControllerにコンストラクタ(など)がある

ILoggerです:これはMicrosoft.Extensionsを使用して、ログに単純です。 NLogを介したロギング。 ISomethingRepository:これはすべての仕事をします(まあ...それの執行、本当に)。それはデータベースを呼び出し、物事を取得します。 GetStuff()というメソッドがあり、単純にStuffのリストを返します。このリポジトリはデータベースに依存しており、コンポーザを介してリポジトリに注入されます。
IExceptionSvc:これは、呼び出し元にJSON形式の復帰のための500のエラー応答を返すメソッドを持っているだけでダム少しサービスです。

私はリポジトリにGetStuff()の実装を呼び出しますコントローラでGetStuff()アクションを、テストしたいです。

私は現在、次のコードは、私のテストプロジェクトでは、内スタブがあります。

public void GetStuff_Is_Awesome() 
     { 
      Mock<ILogger<SomethingController>> logger = new Mock<ILogger<SomethingController>>(); 
      Mock<ISomethingRepository> something = new Mock<ISomethingRepository>(); 
      Mock <IExceptionSvc> ex = new Mock<IExceptionSvc>(); 
      SomethingController sc = new SomethingController(logger.Object, something.Object, ex.Object); 

sc.GetStuff(); 

//...what now? What am I looking for? Am I going to see a list of stuffs here? 

} 

私はちょうど期待するかを知りたいですか?スタッフのリストが返されたかどうかをテストしていますか?それをどうやってテストするのですか?ここで

は、(基準ためにレポのコンストラクタで)リポジトリに)GetStuff(の実装です:

private readonly ApplicationDbContext _context; 
     private readonly ILogger<SomethingRepository> _logger; 

     public SomethingRepository(ApplicationDbContext context, 
      ILogger<SomethingRepository> logger) 
     { 
      _context = context; 
      _logger = logger; 
     } 

public List<StuffViewModel> GetStuff() 
     { 
      List<StuffViewModel> stuffs = null; 
      stuffs = _context.Stuffs.OrderBy(b => b.Name).Select(b => new StuffViewModel 
       { 
        Id = b.Id, 
        Name = b.Name 
       }).ToList(); 

return stuffs; 
      } 
+0

私に例を挙げてもらえますか? – crackedcornjimmy

+0

私は今すぐGetStuff()実装を追加しました。 – crackedcornjimmy

+0

'GetStuff'がアクションであると仮定すると、戻り値は' ActionResult'になります。次に、その戻り値を検査して、テストするさまざまなことをアサーションする必要があります。 –

答えて

3

配置として考え、法アサート

public void GetStuff_Is_Awesome() 
{ 
    //arrange 
    Mock<ILogger<SomethingController>> logger = new Mock<ILogger<SomethingController>>(); 
    Mock<ISomethingRepository> something = new Mock<ISomethingRepository>(); 
    Mock <IExceptionSvc> ex = new Mock<IExceptionSvc>(); 
    SomethingController sc = new SomethingController(logger.Object, something.Object, ex.Object); 

    //act 
    sc.GetStuff(); 

    //assert 
} 

だから、あなたはをアサートして何かが起こったか、何かが呼ばれたとします。

ドメインの詳細、またはISomethingRepositoryを知らなくても、あなたメソッドが呼び出されたことを表明できます

something.Verify(m => m.MethodToCheckIfCalled()); 

その他のオプション等の設定にMethodToCheckIfCalledの戻り値であるとの結果を主張するだろう

public ActionResult GetStuff() 
{ 
    var data = _something.GetFromRepo(); 
    return View(data); 
} 
..

は次のようになりますあなたのコントローラ上のGetStuff方法を想定すると、

私は次のようにします:

public void GetStuff_Is_Awesome() //please don't call it this 
{ 
    //arrange 
    Mock<ILogger<SomethingController>> logger = new Mock<ILogger<SomethingController>>(); 
    Mock<ISomethingRepository> something = new Mock<ISomethingRepository>(); 
    Mock <IExceptionSvc> ex = new Mock<IExceptionSvc>(); 
    SomethingController sc = new SomethingController(logger.Object, something.Object, ex.Object); 

    //setup your something mock GetFromRepo method to return a List of StuffViewModel 
    something.Setup(m=> m.GetFromRepo()) 
     .Returns(new List<StuffViewModel>(){Id = 1, Name = "Test"}); 

    //act 
    var result = sc.GetStuff(); 

    //assert 

    //safely cast result to ViewResult 
    var viewResult = result as ViewResult; 

    Assert.IsNotNull(viewResult); 
    Assert.IsNotNull(viewResult.Model); 

    // add additional checks on the Model.. loads of ways of doing this 
    var viewResultModel = viewResut.Model as List<StuffViewModel>; 

    Assert.AreEqual(1, viewResultModel.First().Id); 
    Assert.AreEqual("Test", viewResultModel.First().Name); 
} 
+0

私はGetStuff()の実装を追加しました。それは特異性を助けますか? – crackedcornjimmy

+1

例を編集した回答 – Alex

+0

私はあなたの答えのように何かしました、そして、ここで少しの光を見ています。しかし、私に届く1つの項目は、テストが実際にデータベースにヒットしないということです。したがって、データは返されません。これは期待されていますか? – crackedcornjimmy