[Test]不需要Web伺服器也可以測程式碼
在沒有導入MVC或是Layer切割不明的情況下, 要做Web程式碼的單元測試總是很難,
但Phil Haack做了一個模擬器HttpSimulator, 讓我們可以沒有Web Server亦能測試,
雖然這篇部落格的文章有點舊了, 仍然很有參考價值.
雖然App_Code放程式很方便, 但個人還是習慣用類別庫, 方便管理, 佈署及測試.
有時會遇到如下的程式碼, 將Session加工的類別, 先不論這樣的設計好或壞,
但單元測試就有問題了, 我要怎麼做出Session呢?
{
HttpSessionState session;
public Class1(HttpSessionState session)
{
this.session = session;
SessionHandler();
}
private void SessionHandler()
{
// ...
}
public string GetSessionValue(string key)
{
return this.session[key] as string;
}
}
1. 目前的功力, 我當然是做不出來.
2. 在G大神的協助下找到了Phil Haack - Unit Test Web Code Without A Web Server Using HttpSimulator
Haack很nice的把code都送給大家了, 所以
1. 你可拿來研究System.Web
2. 可拿來單元測試Session or Request
經測試這個Sample是 ok滴, 如他所言:
The actual path passed into the simulator doesn’t matter. It’s all simulated.
可以讓我們可以輕量地寫測試碼, 真是太感恩了.
///GetValue 的測試
///</summary>
[TestMethod()]
public void GetValueTest()
{
using (new HttpSimulator("/", @"c:\inetpub\").SimulateRequest())
{
HttpContext.Current.Session["Test"] = "true";
Class1 target = new Class1(HttpContext.Current.Session);
Assert.AreEqual("true",target.GetSessionValue("Test"));
}
}
經91大授權
最後加上91大的建議, 讓我增進了不少知識 (拜)
除非又要用moq之類的直接去注入裡面的值,但我認為session這種case並不適用,那是寫法的問題。更簡單的方式,至少也要抽成public property讓外面可以控制。
這樣的production code才能有可測試性。
如果只是影響自己 應該不會太難啦, public一個property出來,然後給預設值是session的值,如果外面有給值,就按照外面給的。
這樣做unit test的時候,就能和production code避開,又能測試當session值是我們的test case的時候 production code可以如同預期的正常運作
UI與核心程式還是會建議按照layer去切開囉,至少模組要切開