2016-05-25 48 views
0

我想寫一個單元測試來測試我的控制器使用會話。我理解httpcontext只是從瀏覽器的請求中生成的概念,並且由於調用控制器操作形式單元測試,所以當前上下文將爲空。單元測試會話仍然返回null後Mocking

我試圖根據這篇文章的第一部分http://www.dontpaniclabs.com/blog/post/2011/03/22/testing-session-in-mvc-in-four-lines-of-code/解決這個問題,但它仍然不適合我。看到我的代碼如下。

[TestFixtureSetUp] 
    public void Configure_AutoMapper() 
    { 
     _product = new ProductViewModel() 
     { 
      Id = Guid.NewGuid(), 
      Category = Guid.Parse("72E42A11-DFA4-4AB9-A735-5CD5C18396D4"), 
      Brand = Guid.Parse("96E68B67-60FB-4531-898E-815433B44D89"), 
      Description = "From test", 
      CostPrice = Parse("17.00"), 
      SalePrice = Parse("25.00"), 
      Quantity = 7, 
      BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415") 
     }; 

     var context = new Mock<ControllerContext>(); 
     var session = new Mock<HttpSessionStateBase>(); 
     context.Setup(m => m.HttpContext.Session).Returns(session.Object); 
     _productsController = new ProductsController {ControllerContext = context.Object}; 

     var userSessionInfo = new UserSessionViewModel() 
     { 
      FirstName = "Junior", 
      LastName = "Labolz", 
      BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415") 
     }; 

     SessionHelper.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo); 
    } 


    [Test] 
    public void Display_Products_List_On_View_Products_Button_Click() 
    { 
     //Set Up 

     //Act 
     var viewResult = (ViewResult)_productsController.Index(); 

     //Assert 
     Assert.That(string.Empty, Is.EqualTo(viewResult.ViewName)); 
    } 


    public static void AddUserDetailsToSession(string sessionName, UserSessionViewModel userSessionDetails) 
    { 
     HttpContext.Current.Session.Add(sessionName, userSessionDetails); 
    } 

**基於理查德的答案,我把它改成**

 var context = new Mock<ControllerContext>(); 
     var session = new Mock<HttpSessionStateBase>(); 
     context.Setup(m => m.HttpContext.Session).Returns(session.Object); 
     var userSessionInfo = new UserSessionViewModel() 
     { 
      FirstName = "Junior", 
      LastName = "Labolz", 
      BusinessId = Guid.Parse("BDF9FB7F-DB40-4365-9872-AECD616ED415") 
     }; 
     context.Object.HttpContext.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo); 

     _productsController = new ProductsController {ControllerContext = context.Object}; 

產品的控制器構造

public ProductsController() 
    { 
     _productService = new ProductServiceClient(); 
     _userSessionViewModel = (UserSessionViewModel)SessionHelper.GetSessionDetail(SessionHelper.UserDetails); 
    } 

獲取會話方法

public static object GetSessionDetail(string sessionName) 
    { 
     return HttpContext.Current.Session[sessionName]; 
    } 

回答

0

我可以看到你的代碼包含一個直接引用HttpContext.Current的靜態函數。如果你想單元測試你不能這樣做,你必須改用HttpContextBase的注入實例。

在你的單元測試中,這些實例將是你的模擬上下文。在生產中,當請求HttpContextBase時,您將設置容器以注入HttpContext.Current。

我會重寫你的靜態方法是一個擴展方法:

public static void AddUserDetailsToSession(this HttpContextBase context, 
    string sessionName, UserSessionViewModel userSessionDetails) 
{ 
    context.Session.Add(sessionName, userSessionDetails); 
} 

然後從測試調用它:

context.Object.AddUserDetailsToSession(SessionHelper.UserDetails, userSessionInfo); 
+0

我仍然得到一個空引用異常,也許是因爲我也是試圖讀我的productController構造函數中的會話? –

+0

我已更新我的代碼,請爲我尋找。我將其改爲使用擴展方法,在我的更新中有一個標題「基於理查德的回答」。我也向你展示了我的產品控制器中的內容 –

+0

不能在任何地方使用HttpContext.Current - 您可以從ControllerContext獲取HttpContext。您不應該從控制器構造函數訪問Session,因爲在調用時沒有上下文。 – Richard

相關問題