2016-10-31 143 views
1

我一直在使用實體框架開發ASP.NET MVC項目Visual Studio 2012 Ultimate。我必須在我的解決方案中包含一個單元測試項目。我的問題是測試方法(稱爲Index())無法識別控制器的Index()操作中的會話 。我的單元測試的方法是:在主控制器單元測試無法識別會話

using System; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Web.Mvc; 
using ELSORegistry; 
using ELSORegistry.DataAccess; 
using ELSORegistry.Controllers; 



namespace ELSORegistryUnitTests 
{ 
    [TestClass] 
    public class FirstControllerTest 
    { 
     [TestMethod] 
     public void Index() 
     { 
      //Arange 
      HomeController controller = new HomeController(); 

      //Act 
      Guid? myGuid = new Guid("941b1615-f21b-4e2c-8fa8-0ed0d3f2de53"); 
      ViewResult result = controller.Index(myGuid) as ViewResult; 

      //Assert 
      Assert.IsNotNull(result); 
     } 
    } 
} 

我的索引()操作是:

using System; 
using System.Diagnostics.Contracts; 
using System.Web.Mvc; 
using ELSORegistry.DataAccess; 
using ELSORegistry.Models; 
using Kendo.Mvc.UI; 
using WebGrease.Css.Extensions; 
using ELSORegistry.Extensions; 



using System.Collections.Generic; 
using System.Data; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Data.Entity.Validation; 
using System.Linq; 
using Kendo.Mvc.Extensions; 
using System.Diagnostics; 
using ELSORegistry.Helpers; 
using Newtonsoft.Json; 


namespace ELSORegistry.Controllers 
{ 
    [Authorize] 
    public class HomeController : Controller 
    { 
     [Authorize(Roles = "ECLS Center Data Manager, ECLS Center Administrator,ECLS Center Data Viewer, ECLS Center Data Entry")] 
     //[RequireHttps] // Enable for production 
     public ActionResult Index(Guid? CenterId) 
     { 
      //---------------------------------------- 
      // Remove references to previous patients 
      //----------------------------------------  
      Session.Remove("Patient"); 
      Session.Remove("PatientSummary"); 
      Session.Remove("Run"); 
      Session.Remove("RunDetail"); 
      Session.Remove("Addendum"); 

      // if user have this session then he will get edit forms. // Yes if Add new 
      Session.Remove("AddNewMode"); 
      Session.Remove("AddNewRunId"); 
      Center center; 
      if (CenterId == null) 
      { 
       center = Session["Center"] as Center; 
       Contract.Assert(center != null); 
      } 
      else 
      { // set center by selected centerId from dropdownlist 
       center = new Repository().GetCenter(new Guid(CenterId.ToString())); 
       Session["Center"] = center; 
       center = Session["Center"] as Center; 
       Contract.Assert(center != null); 
      } 


      ViewBag.RunCounts = Session["RunCounts"]; 
      ViewBag.ChartSummaries = Session["ChartSummaries"]; 



      return View(new QuickAdd()); 

     } 

我怎樣才能讓從我的單元測試方法會話?預先感謝您的任何幫助。

+2

您需要使用像Moq這樣的模擬工具來模擬Session屬性。 – CodeNotFound

+0

控制器依賴項也在方法中實例化。 – Nkosi

回答

2

要麼手動創建模擬會話,要麼使用模擬框架來模擬將成爲http上下文一部分的會話。基本上這種安排正在複製框架在運行時的功能。

[TestMethod] 
public void Index() { 
    //Arange 
    Guid? myGuid = new Guid("941b1615-f21b-4e2c-8fa8-0ed0d3f2de53"); 
    var center = new Center(); 
    var session = Mock.Of<HttpSessionStateBase>(); 
    session["Center"] = center; 
    var mockSession = Mock.Get(session); 
    mockSession.Setup(m => m["Center"]).Returns(center); 

    var httpcontext = Mock.Of<HttpContextBase>(); 
    var httpcontextSetup = Mock.Get(httpcontext); 
    httpcontextSetup.Setup(m => m.Session).Returns(session); 

    var mockRepository = new Mock<IRepository>(); 
    mockRepository.Setup(m => m.GetCenter(myGuid.Value)).Returns(center); 

    HomeController controller = new HomeController(mockRepository.Object); 
    controller.ControllerContext = new ControllerContext { 
     HttpContext = httpcontext, 
     Controller = controller 
    }; 

    //Act 
    ViewResult result = controller.Index(myGuid) as ViewResult; 

    //Assert 
    Assert.IsNotNull(result); 
} 

上面的例子使用Moq來模擬依賴關係。該控制器也進行了重構,以通過抽象存儲庫來實現更好的測試能力。

public interface IRepository { 
    Center GetCenter(Guid guid); 
} 

public class Repository : IRepository { 
    //...other code removed for brevity 
} 

[Authorize] 
public class HomeController : Controller { 
    private IRepository repository; 

    public HomeController(IRepository repository) { 
     this.repository = repository; 
    } 

    [Authorize(Roles = "ECLS Center Data Manager, ECLS Center Administrator,ECLS Center Data Viewer, ECLS Center Data Entry")] 
    //[RequireHttps] // Enable for production 
    public ActionResult Index(Guid? CenterId) { 
     //---------------------------------------- 
     // Remove references to previous patients 
     //----------------------------------------  
     Session.Remove("Patient"); 
     Session.Remove("PatientSummary"); 
     Session.Remove("Run"); 
     Session.Remove("RunDetail"); 
     Session.Remove("Addendum"); 

     // if user have this session then he will get edit forms. // Yes if Add new 
     Session.Remove("AddNewMode"); 
     Session.Remove("AddNewRunId"); 
     Center center; 
     if (CenterId.GetValueOrDefault() == Guid.Empty) { 
      center = Session["Center"] as Center; 
      Contract.Assert(center != null); 
     } else { // set center by selected centerId from dropdownlist 
      center = repository.GetCenter(CenterId.Value); 
      Session["Center"] = center; 
      center = Session["Center"] as Center; 
      Contract.Assert(center != null); 
     } 

     ViewBag.RunCounts = Session["RunCounts"]; 
     ViewBag.ChartSummaries = Session["ChartSummaries"]; 

     return View(new QuickAdd()); 
    } 
} 
+0

感謝您的關注和幫助。請建議如何包含DLL與模擬。 – alenan2013

+1

使用nuget並添加'Moq'來測試項目。 – Nkosi

+0

非常感謝:) – alenan2013