2012-03-14 86 views
0

我有一個非常標準的.NET MVC 3應用程序,它使用Ninject進行依賴注入。我試圖單元測試的是從控制器返回的視圖。有一個控制器上有一個組服務,該服務有一個存儲庫。服務首先檢查該組是否存在,如果存在,則返回false並返回錯誤。然後控制器檢查布爾值以確定是否將用戶移動到組列表或保留在當前頁面上並顯示一個值。具有依賴注入服務和存儲庫的單元測試控制器

控制器

[HttpPost] 
public ActionResult AddGroup(Group g) 
{ 
    string error = string.Empty; 
    if (groupService.Save(g, CurrentUser, out error)) 
    { 
     return RedirectToAction("GetGroups"); 
    } 
    else 
    { 
     ViewData["Error"] = error; 
     return View("AddGroup"); 
    } 
} 

服務

[Inject] 
public IGroupRepository CurrentGroupRepo { get; set; } 

public bool Save(Group group, string username, out string error) 
{ 
    error = string.Empty; 
    var found = CurrentGroupRepo.GetGroup(group.Descr, false); 
    if (found != null) 
    { 
     error = "That group alread exists"; 
     return false; 
    } 

    if (group.CreatedBy == null || group.CreatedBy == string.Empty) 
    { 
     group.CreatedBy = username; 
     group.CreatedOn = DateTime.Now; 
     group.IsDeleted =false; 
    } 

    group.ModifiedBy = username; 
    group.ModifiedOn = DateTime.Now; 

    try 
    { 
     if (group.GroupID == 0) 
     { 
      CurrentGroupRepo.AddGroup(group); 
     } 
     else 
     { 
      CurrentGroupRepo.UpdateGroup(group); 
     } 
     return true; 
    } 
    catch (Exception ex) 
    { 
     error = ex.Message + ex.StackTrace; 
     return false; 
    } 
} 

單元測試

[TestMethod] 
public void TestAddGroup() 
{ 
    // Arrange 
    Mock<IUserService> uService = new Mock<IUserService>(); 
    Mock<IGroupService> gService = new Mock<IGroupService>(); 
    Mock<IObservationService> oService = new Mock<IObservationService>(); 
    Mock<IGroupRepository> mockGroupRepo = new Mock<IGroupRepository>(); 

     string error = string.Empty; 
     List<Group> groups = new List<Group>(); 
     Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false }; 
     Mock<IGroupRepository> mockGroupRepo = new Mock<IGroupRepository>(); 

     mockGroupRepo.Setup(cr => cr.GetGroups(It.IsAny<bool>())).Returns(
      delegate { 
       return groups; 
      }); 
     mockGroupRepo.Setup(cr => cr.GetGroup(It.IsAny<string>(), It.IsAny<bool>())).Returns(
      delegate(Group _group) { 
       return groups.Where(f => f.Descr == _group.Descr).FirstOrDefault(); 
      }); 
     mockGroupRepo.Setup(cr => cr.AddGroup(newGroup)).Returns(
      delegate { 
       groups.Add(newGroup); 
       return newGroup; 
      }); 
     gService.SetupGet(d => d.CurrentGroupRepo).Returns(mockGroupRepo.Object); 


    AdminController controller = new AdminController(gService.Object, uService.Object, oService.Object); 
    Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false }; 
    var success = (ViewResult)controller.AddGroup(newGroup); 
    Assert.IsTrue("GetGroups" == success.ViewName); 

    var failure = (ViewResult)controller.AddGroup(newGroup); 
    Assert.IsTrue("AddGroup" == failure.ViewName); 
} 

我試圖給TE st是,當我添加一個組時,它應該工作,然後當我添加同一個組時,它應該轉到不同的視圖。但現在,單元測試正在使用真實的存儲庫而不是嘲弄的存儲庫。如何讓模擬服務上的存儲庫由單元測試來控制,而不是真正使用真正的存儲庫?

回答

2

如果您正在對控制器進行單元測試,那麼您不必擔心存儲庫,因爲您的服務被嘲笑。就控制器而言,沒有存儲庫,只知道它是IGroupService合同。

我看不到你的睾丸是如何使用真實的資料庫給你的代碼。如果你想改變你的測試,你需要提供一些模擬的IGroupService模擬迴應。

您需要對接受Mocked Repository的GroupService進行第二次單元測試。

IMO單元測試應該只測試一個類,其他所有 應該被嘲笑或是非常簡單的dto對象。如果你是 做更多,那麼這是一個綜合測試。

+0

我必須缺少一些非常簡單的東西,因爲它一直保存到數據庫而不是單元測試中的集合。我已經更新了測試,以向我展示手動設置存儲庫並將其放置在模擬服務上,但代表從不會被調用。我是否必須創建一個DefaultModule來禁止NinjectModule,併爲單元測試創​​建新的綁定以模擬? – Josh 2012-03-15 14:02:12

+0

@Josh我不是一個ninject專家。我使用溫莎,但概念應該是相同的。從我所看到的情況來看,沒有必要將存儲庫模擬出來,因爲控制器不使用存儲庫。事實上,你的IoC甚至不應該在單元測試級別上相關。你是否展示了單元測試線上的所有內容,有沒有你沒有展示的設置? – Bronumski 2012-03-15 14:22:59

+0

你的答案最終指向了我正確的方向。我會發佈一個跟進。 – Josh 2012-03-15 14:30:52

0

根據Bronumski的建議,我最終簡化了一下。這是代碼,並且所有代碼似乎都很好。

 [TestMethod] 
    public void TestAddGroup() { 
     // Arrange 
     Group newGroup = new Group() { Descr = "Test Group 1234566", IsDeleted = false }; 
     gService.Setup(cr => cr.Save(It.IsAny<Group>(), It.IsAny<string>())).Returns(""); 

     AdminController controller = new AdminController(gService.Object, uService.Object, oService.Object); 

     // Act 
     var success = (RedirectToRouteResult)controller.AddGroup(newGroup); 
     Assert.IsTrue("GetGroups" == success.RouteValues["action"].ToString()); 

     gService.Setup(cr => cr.Save(It.IsAny<Group>(), It.IsAny<string>())).Returns("Error"); 
     var failure = (ViewResult)controller.AddGroup(newGroup); 
     Assert.IsTrue("AddGroup" == failure.ViewName); 
    } 
相關問題