2011-09-26 60 views
1

我有一個需要提供操作測試的項目。我的approuch一直在確保操作不依賴於任何他們沒有收到的參數,從而使用ValueProviders和ModelBinder。因此,我會通過HTTPContextBase等MVC依賴於HTTPContext的測試操作

但是,我現在有一個動作,它使用靜態類是HTTPContext的包裝來訪問會話和身份。因此,似乎我必須模擬出HTTPContext來測試此操作。我想不是太複雜,但它只是感覺不對。

我的直覺是應該重新開發靜態類,以便使用HTTPSessionStateBase和IPrinicple實例化並將它們用作內部存儲。然後,我可以在動作中從動作參數中實例化這個包裝器,使動作和包裝器類更友好。

這是一個建議approuch或沒有任何人有任何其他的想法,我是不是會改變我的靜態類爲實例嗎?

回答

0

我強烈建議使用MvcContrib - testhelpers 瞭解如何從CodePlex
使用您可以從nuget CodePlex從
祝你好運下載,也可以直接!

+0

有一個快速瀏覽一下他們,特別是我的情況,看來你是能夠建立一個控制範圍內,但不會出現是初始化ASP的HTTPContext.Current的任何東西。因此,當我的動作調用靜態包裝類時,它依次嘗試訪問HTTPContext.Current.Session,我得到一個錯誤。我想我只需要經歷在我的測試中初始化HTTPContext.Current的痛苦? – ricardo

+0

@ricardo它看起來像你不使用DI。注入httpContext並且所有的問題都會消失......使用靜態httpContext.Current是一個錯誤,你可以在你的情況下看到它。祝你好運! – gdoron

1

我認爲使用Moq來模擬一個HttpContext只是你可能想要嘗試的方式。

[TestMethod] 
public void Test() 
{ 

    var context = new Mock<HttpContextBase>(); 
    var request = new Mock<HttpRequestBase>(); 
    context.Setup(c => c.Request).Returns(request.Object); 

    HomeController controller = new HomeController(); 

    controller.ControllerContext = new ControllerContext(context , new RouteData(), controller); 

    .... 
    ........... 
} 




更新時間:
如果您想嘲笑HttpSession中(如在評論中提及gdoron)的情況。它並不是很複雜,因爲你是Mocking,並不意味着你必須構建完整的,真實的對象及其所有屬性。

假設您的控制器將

  1. 檢查是否用戶進行身份驗證。
  2. 獲取標識名稱。
  3. 從Session [「key」]中獲取一個值。
  4. 操縱cookie。

的代碼可能是這樣的:

[TestMethod] 
public void Test() 
{ 
    ...... 
    ......... 
    var mockedControllerContext = new Mock<ControllerContext>(); 
    mockedControllerContext.SetupGet(p => p.HttpContext.Session["key"]).Returns("A value in session"); 
    mockedControllerContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);  
    mockedControllerContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("An identity name"); 
    mockedControllerContext.SetupGet(p => p.HttpContext.Response.Cookies).Returns(new HttpCookieCollection()); 

    HomeController controller = new HomeController(); 
    controller.ControllerContext = mockedControllerContext.Object; 
    ..... 
    ...... 

} 
+0

實現模擬會話時所寫的內容非常複雜! – gdoron

+0

問題是Contoller的HttpContext是從靜態ASP.NET HttpContext中設置的。因此,簡單地構建HttpContextBase並將其附加到Controller的上下文不會影響靜態HttpContext。我的動作調用一個靜態包裝器,它無法訪問ControllerContext並直接訪問ASP.NET HttpContext。除非我誤解了某些東西,否則我覺得這個設計是有缺陷的,靜態包裝應該被重新開發爲一個採用控制器的HttpContext的實例,然後我可以嘲笑它的生活......如果我選擇。 – ricardo

+0

我認爲你是對的。既然你選擇了靜態保存的東西。你失去了靈活性(但它可能會節省一些資源的好處) –