2012-03-14 89 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); 
    } 
相关问题