我有一個非常標準的.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是,當我添加一個組時,它應該工作,然後當我添加同一個組時,它應該轉到不同的視圖。但現在,單元測試正在使用真實的存儲庫而不是嘲弄的存儲庫。如何讓模擬服務上的存儲庫由單元測試來控制,而不是真正使用真正的存儲庫?
我必須缺少一些非常簡單的東西,因爲它一直保存到數據庫而不是單元測試中的集合。我已經更新了測試,以向我展示手動設置存儲庫並將其放置在模擬服務上,但代表從不會被調用。我是否必須創建一個DefaultModule來禁止NinjectModule,併爲單元測試創建新的綁定以模擬? – Josh 2012-03-15 14:02:12
@Josh我不是一個ninject專家。我使用溫莎,但概念應該是相同的。從我所看到的情況來看,沒有必要將存儲庫模擬出來,因爲控制器不使用存儲庫。事實上,你的IoC甚至不應該在單元測試級別上相關。你是否展示了單元測試線上的所有內容,有沒有你沒有展示的設置? – Bronumski 2012-03-15 14:22:59
你的答案最終指向了我正確的方向。我會發佈一個跟進。 – Josh 2012-03-15 14:30:52