2011-05-10 54 views
1

按斯科特Hanselman的模擬例子http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx我嘗試使用MockHelpers作爲代碼片段嘲笑的HttpContext下面如何添加會話模擬httpcontext?

controller = GetAccountController(); 

ActionResult result = controller.ChangePassword(); 

HttpContextBase hb = MvcMockHelpers.FakeHttpContext("~/Account/ChangePassword"); 
hb.Session.Add("id", 5); 

// Assert Assert.AreEqual(5, (int)hb.Session["id"]); 

我注意到,不加入會話並沒有收到任何錯誤要麼。會話對象的屬性具有低於值

計數= 0,CODEPAGE = 0,含量= NULL,IsCookieLess = NULL,IsNewSession = NULL,IsReadOnly = NULL,IsSynchronized =零,鍵= NULL,LCID = 0,模式= off,SessionId = null,Static Objects = null,SynRoot = null,TimeOut = 0

我對Rhino mock和Moq獲得了同樣的結果。

請教我如何添加會話模擬httpcontext。

在此先感謝。

回答

2

您引用的代碼說明了如何僞造httpcontext - 當您調用「hb.Session.Add」時,它實際上並不執行任何操作 - 它只是停止測試,因爲依賴於HttpContext而失敗。

3

下面是我用來模擬不僅會話,但大多數其他對象,你需要(請求,響應等),這個代碼是史蒂夫桑德森和其他人的代碼集合,以及我自己的,筆記該會話使用字典

using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.Web; 
using System.Web.Routing; 
using System.Web.Mvc; 

namespace ECWeb2.UnitTests { 
    public class ContextMocks { 
     public Moq.Mock<HttpContextBase> HttpContext { get; private set; } 
     public Moq.Mock<HttpRequestBase> Request { get; private set; } 
     public Moq.Mock<HttpResponseBase> Response { get; private set; } 
     public RouteData RouteData { get; private set; } 
    public ContextMocks(Controller onController) { 
     // Define all the common context objects, plus relationships between them 
     HttpContext = new Moq.Mock<HttpContextBase>(); 
     Request = new Moq.Mock<HttpRequestBase>(); 
     Response = new Moq.Mock<HttpResponseBase>(); 
     HttpContext.Setup(x => x.Request).Returns(Request.Object); 
     HttpContext.Setup(x => x.Response).Returns(Response.Object); 
     HttpContext.Setup(x => x.Session).Returns(new FakeSessionState()); 
     Request.Setup(x => x.Cookies).Returns(new HttpCookieCollection()); 
     Response.Setup(x => x.Cookies).Returns(new HttpCookieCollection()); 
     Request.Setup(x => x.QueryString).Returns(new NameValueCollection()); 
     Request.Setup(x => x.Form).Returns(new NameValueCollection()); 

     // Apply the mock context to the supplied controller instance 
     RequestContext rc = new RequestContext(HttpContext.Object, new RouteData()); 
     onController.ControllerContext = new ControllerContext(rc, onController); 
     onController.Url = new UrlHelper(rc); 
    } 

    ContextMocks() { 
    } 

    // Use a fake HttpSessionStateBase, because it's hard to mock it with Moq 
    private class FakeSessionState : HttpSessionStateBase { 
     Dictionary<string, object> items = new Dictionary<string, object>(); 
     public override object this[string name] { 
      get { return items.ContainsKey(name) ? items[name] : null; } 
      set { items[name] = value; } 
     } 
    } 
} 

}

1

您可以使用由Outercurve基金會提供給一個正常請求的處理過程中可以使用模擬會話狀態和其他物體的MVC的Contrib庫(僞造HttpRequest,HttpResponse等)。

http://mvccontrib.codeplex.com/(或使用的NuGet下載它)

它包含TestHelper library它可以幫助你快速創建單元測試。

例如:

[TestMethod] 
public void TestSomething() 
{ 
    TestControllerBuilder builder = new TestControllerBuilder(); 

    // Arrange 
    HomeController controller = new HomeController(); 

    builder.InitializeController(controller); 

    // Act 
    ViewResult result = controller.About() as ViewResult; 

    // Assert 
    Assert.IsNotNull(result); 
} 

使用由MVC的Contrib TestHelper庫提供的TestControllerBuilder類型可以快速初始化控制器並初始化它的內部數據成員(HttpContext的是,HttpSession,TempData的...)。

當然,HttpSessionState本身也是用這種方式模擬的,所以添加一些東西(Session.Add)實際上不會做什麼。按照意圖,我們嘲笑它。

好像你想模擬HttpContext,但仍然設置工作會話狀態。聽起來像是你想要做的事如下所述:

http://jasonbock.net/jb/Default.aspx?blog=entry.161daabc728842aca6f329d87c81cfcb

1

這是我最常做的

//Mock The Sesssion 
_session = MockRepository.GenerateStrictMock<httpsessionstatebase>(); 
_session.Stub(s => s["Connectionstring"]).Return(Connectionstring); 

//Mock The Context 
_context = MockRepository.GenerateStrictMock<httpcontextbase>(); 
_context.Stub(c => c.Session).Return(_session); 

var databaseExplorerController = new DatabaseExplorerController(repository); 

//Assign COntext to controller 
databaseExplorerController.ControllerContext = new ControllerContext(_context, new RouteData(), 
                    _databaseExplorer); 

我在

http://www.gigawebsolution.com/Posts/Details/66/Mock-Session-in-MVC3-using-Rhino-Mock

寫這個小aricle

希望這會有所幫助

0

有點遲,但這是用途。

I''m使用MOQ框架從https://code.google.com/p/moq/

現在會話是在控制器中實現使用。

private class MockHttpSession : HttpSessionStateBase 
    { 
     readonly Dictionary<string, object> _sessionDictionary = new Dictionary<string, object>(); 
     public override object this[string name] 
     { 
      get 
      { 
       object obj = null; 
       _sessionDictionary.TryGetValue(name, out obj); 
       return obj; 
      } 
      set { _sessionDictionary[name] = value; } 
     } 
    } 

    private ControllerContext CreateMockedControllerContext() 
    { 
     var session = new MockHttpSession(); 
     var controllerContext = new Mock<ControllerContext>(); 
     controllerContext.Setup(m => m.HttpContext.Session).Returns(session); 

     return controllerContext.Object; 
    } 

    [TestMethod] 
    public void Index() 
    { 
     // Arrange 
     MyController controller = new MyController(); 
     controller.ControllerContext = CreateMockedControllerContext(); 

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

     .... 
    }