在創建單元測試時,有沒有辦法在ASP.Net Web窗體中模擬/僞造會話對象?如何在ASP.Net Web窗體中模擬/僞造會話對象?
我目前正在將用戶詳細信息存儲在由我的業務邏輯訪問的會話變量中。
當單獨測試我的業務邏輯時,會話不可用。這似乎表明設計不好(雖然我不確定)。業務邏輯層應該首先訪問會話變量嗎?
如果是這樣,那麼我將如何去交換用戶測試的虛假對象的細節?
在創建單元測試時,有沒有辦法在ASP.Net Web窗體中模擬/僞造會話對象?如何在ASP.Net Web窗體中模擬/僞造會話對象?
我目前正在將用戶詳細信息存儲在由我的業務邏輯訪問的會話變量中。
當單獨測試我的業務邏輯時,會話不可用。這似乎表明設計不好(雖然我不確定)。業務邏輯層應該首先訪問會話變量嗎?
如果是這樣,那麼我將如何去交換用戶測試的虛假對象的細節?
在ASP.NET中,您無法創建HttpSessionState的測試雙因爲它是sealed
。是的,這對於ASP.NET的原始設計師來說是不好的設計,但對此沒有太多要做。
這是TDD和其他固體實踐者基本上放棄ASP.NET而轉向ASP.NET MVC和其他更可測試的框架的原因之一。在ASP.NET MVC中,HTTP會話由抽象的HttpSessionStateBase類建模。
您可以採取類似的方法,讓對象在抽象會話上工作,然後在ASP.NET環境中運行時包裝真正的HttpSessionState類。根據具體情況,您甚至可以重用System.Web.Abstractions中的類型,但如果不是,您可以定義自己的類型。
在任何情況下,您的業務邏輯是您的業務邏輯是域模型它應該獨立於任何特定的運行時技術建模,所以我會說它不應該首先訪問會話對象。
如果你絕對需要使用測試雙打涉及HttpSessionState單元毒鼠強,這依舊可能帶有一定侵入性的動態模擬考試,如TypeMock或Moles,althought這些攜帶大量的缺點,以及(見this comparison of dynamic mocks)。
你的直覺是正確的---你不應該從你的業務邏輯訪問ASP.NET框架的部分。這將包括會話。
要回答你的第一個問題,你可以使用像Typemock隔離器的產品,但如果你在一個界面重構代碼換到會話訪問,你會更好模擬靜態類(即IHttpSession。)然後你可以模擬IHttpSession。
一種方法是將lambda表達式傳遞給代碼,該代碼將字符串(或其他對象)作爲輸入,並使用它來設置Session對象或測試容器。
但是,正如其他人所說,將訪問Session對象移出BLL是個好主意。
在Asp.Net webforms中,你不能逃避框架進入你的代碼來自aspx頁面的事實。我同意你的業務層不應直接觸及asp.net特定的組件,但你必須有一個模型的存儲容器,並且在asp.net中的會話是一個很好的領域。因此,一種可能的方法是創建ISessionManager用於在業務層內進行交互。然後,通過使用HttpSessionState實現具體類型...順便說一句,一個好的技巧是使用HttpContext.Current.Session來實現訪問器/ getters從HttpSessionState。 您的下一個挑戰將是如何將它們連接在一起。
你可以用4行代碼來完成。雖然這並不涉及將業務邏輯層移出會話的先前評論,但如果您使用與會話密切相關的遺留代碼(我的場景),則有時您可能需要執行此操作。
的命名空間:
using System.Web;
using System.IO;
using System.Web.Hosting;
using System.Web.SessionState;
代碼:
HttpWorkerRequest _wr = new SimpleWorkerRequest(
"/dummyWorkerRequest", @"c:\inetpub\wwwroot\dummy",
"default.aspx", null, new StringWriter());
HttpContext.Current = new HttpContext(_wr);
var sessionContainer = new HttpSessionStateContainer(
"id", new SessionStateItemCollection(),
new HttpStaticObjectsCollection(), 10, true,
HttpCookieMode.AutoDetect, SessionStateMode.InProc, false);
SessionStateUtility.AddHttpSessionStateToContext(
HttpContext.Current, sessionContainer);
然後,您可以參考會話沒有得到一個NullReferenceException錯誤:
HttpContext.Current.Session.Add("mySessionKey", 1);
這是一個代碼組合我從下面的文章編譯:
也看到我對這個問題的答案 - http://stackoverflow.com/a/8487847/232593 – 2011-12-14 10:48:39