程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> 盡可能擺脫對HttpContext的依賴

盡可能擺脫對HttpContext的依賴

編輯:關於ASP.NET

今天主要談論HttpContext的依賴問題。

在ASP.NET中進行單元測試的天敵便是HttpContext,它是ASP.NET的核心,極端復雜,卻無法進行 Mock1——可見微軟能夠寫出那麼龐大的ASP.NET框架真不那麼容易。現在這個狀況改善了不 少,因此大家已經可以使用System.Web.Abstractions.dll了,這個程序集中提供了對於HttpContext的抽 象,也就是HttpContextBase抽象類。因此在ASP.NET MVC中,各種組件均依賴於HttpContextBase而不是 HttpContext。這是一個優秀的做法,大家以後可以盡可能地擺脫HttpContext了。

不過這似乎又是一個悖論。雖然已經可以對HttpContext進行Mock(這點增強了可測試性),但是過度 依賴HttpContext對於單元測試來說也是一個傷害。這是HttpContext對象的天性所致:它實在太復雜了。 您應該已經察覺到,這是個集萬千寵愛於一身的對象,從請求,回復,應用程序,緩存……幾乎包含了 Web應用程序需要的所有信息。如果要測試一個依賴於HttpContext的方法,您勢必要為HttpContext的 Mock對象填充各種信息——其復雜程度視業務而定。而且,Mock關注的是“行為”,也就是說它關注的是 做一件事情所使用“路徑”。那麼如果做一件事情可以采用多個路徑又會怎樣?是否需要在測試之前准備 好所有的路徑,並且驗證被測試的代碼“采用了,並僅僅采用了其中一條路徑”?因此,Stub慢慢進入人 們的視線。Stub關注的是“狀態”……這就是另一個話題了,還會涉及到采用Record & Replay還是 Arrange-Act-Assert方式來進行單元測試,暫且不提。

之前談到對視圖進行單元測試時,老趙曾經談起在視圖中應該只使用ViewData中的數據。這不是第一 次說起要放棄HttpContext了,自從有了“抽象”這一有利武器後,一切“不和諧”因素都能夠被分離。 試想在MVP模式中,View和Presenter都使用各自的抽象進行交互,一切Web控件,HttpContext等對象都不 復存在了,大家眼中只有“數據”和“模型”。同樣,在ASP.NET MVC的Action方法中,也不應該使用 HttpContext,這是基於良好的“可測試性”而考慮的。您可能會想,現在的HttpContextBase對象已經可 以Mock了啊。沒錯,它的確“可以”,但是這樣做會引起單元測試代碼的膨脹,因為測試代碼中的相當部 分必須關注在測試數據的准備,而不是被測試的功能上。對於一個Action方法來說,它關注的應該是用戶 與業務邏輯的交互,而不是“如何把HTTP請求轉化為可用的數據”。其實說到底,還是要“分離關注點” 。

在ASP.NET MVC中負責“轉化數據”的層次為Model Binder。關於這一點,現有的“示例”大都關注把 Form或QueryString中的數據轉化為Action參數上,不過Model Binder可用的地方其實更多。例如在《最 佳實踐》的代碼中,原本AccountController的Delete方法實現如下:

public ActionResult Delete(string userName)
{
  this.MiddleTier.UserManager.Delete(userName);

  Uri urlReferrer = this.Request.UrlReferrer;
  return this.Redirect(urlReferrer.ToString());
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved