日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

解析ASP.NET MVC項(xiàng)目中視圖的單元測試_.Net教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:談.NET平臺編程語言的未來
在去年的PDC2008召開期間,微軟逐步公開了圍繞.NET和編程語言的很多想法,據(jù)此我們可以饒有興趣地對.NET的未來預(yù)測一番。 .NET平臺以運(yùn)行在通用語言運(yùn)行時(Common Language Runtime,CLR)上的C#和VB.NET作為開端。CLR是通用語言架構(gòu)(Common Language Infrast

關(guān)于視圖的單元測試

說到ASP.NET MVC,我們似乎始終都在關(guān)注對于Controller的測試——雖然Stephen Walther也寫過如何脫離Web Server對View進(jìn)行單元測試,但是他的方法可看而不可用。復(fù)雜的構(gòu)造和預(yù)備,以及對生成的HTML字符串作判斷——這真是在對視圖做單元測試嗎?仔細(xì)分析他的代碼可以發(fā)現(xiàn),這其實(shí)是在對ViewEngine做單元測試。而且,如果真要對ViewEngine做單元測試,也不應(yīng)該像他那樣依賴外部文件。在我看來,他的做法什么都不是……似乎美觀,似乎能博得一些“掌聲”,但是這個掌聲是來自于他的解決方案,還是大家一時的沖動呢?

如果要對視圖做單元測試,還是要將內(nèi)容呈現(xiàn)在瀏覽器中才行。在對網(wǎng)頁做單元測試時,我們一般會使用WatiN等工具操作瀏覽器,打開頁面,再對其DOM元素結(jié)構(gòu)及內(nèi)容作斷言。不過……這是單元測試嗎?可惜這只能算是一種回歸測試或用戶驗(yàn)收測試。因?yàn)�,我們在打開一個頁面的時候,從表現(xiàn)層到業(yè)務(wù)邏輯再到數(shù)據(jù)訪問,應(yīng)用程序的每個部件都在忙碌著。而單元測試講究的是“分離”,分離一切關(guān)注,分離一切依賴。因?yàn)榉蛛x,我們才能準(zhǔn)確定位錯誤;因?yàn)榉蛛x,我們才能在測試中使用我們準(zhǔn)備好的數(shù)據(jù)。

既然要分離,我們就必須遵循一定的使用規(guī)范。在《ASP.NET MVC單元測試最佳實(shí)踐》中我提到,在View中只能使用ViewData中的數(shù)據(jù),而不該依賴其他內(nèi)容(包括HttpContext)。這樣我們就可以自行構(gòu)造ViewData并注入一個視圖對象中。事實(shí)上,這個約定在ASP.NET MVC自帶的項(xiàng)目模板中就被破壞了。請看Views\Shared\LogOnUserControl.ascx,其中通過this.User來查看當(dāng)前用戶的登陸狀態(tài)。這是個定義在傳統(tǒng)Page對象上的屬性,從當(dāng)前HttpContext上直接獲取。如果使用這種方式,我們在單元測試時就難以“模擬”當(dāng)前用戶的登陸狀態(tài),進(jìn)而難以使測試覆蓋到測試的各種情況了。

Lightweight Test Automation Framework

在這里,老趙推薦使用ASP.NET Team提供的Lightweight Test Automation Framework(下文稱之為LTAF)作為測試工具,它目前已經(jīng)在CodePlex上更新至Feb Update版本。這個框架的作用與WatiN和Selenium類似,可操作瀏覽器對應(yīng)用程序編寫回歸測試。雖然在某些方面(例如DOM元素的選�。┎蝗�“競爭對手”,但是LTAF自有其獨(dú)到之處:

由于直接在瀏覽器中運(yùn)行,它天生便支持現(xiàn)有的——以及未來可能出現(xiàn)的任意瀏覽器。
由于直接部署在被測試的網(wǎng)站中,因此測試代碼和網(wǎng)站頁面是在同一個進(jìn)程中。

第一點(diǎn)優(yōu)勢自不必說,而第二點(diǎn)更是關(guān)鍵。試想WatiN和Selenium,都是通過編寫代碼在瀏覽器中打開頁面。這意味著我們的在測試代碼和被測試的網(wǎng)頁分別在不同的進(jìn)程中。在這個前提下,如果我們要將測試代碼中定義的數(shù)據(jù)傳遞給被測試的網(wǎng)頁(也就是視圖對象),我們就必須進(jìn)行跨進(jìn)程的通信。而無論怎么實(shí)現(xiàn),都逃不過“序列化”一途,這無疑增加了復(fù)雜度。而使用LTAF之后,這個問題瞬間煙消云散了,因?yàn)槲覀兛梢灾苯釉趦?nèi)存中“傳遞”測試數(shù)據(jù),一切都只是個引用而已。

不過任何事物都具有兩面性,LTAF也有一些難以天生的,而且是永遠(yuǎn)無法彌補(bǔ)的缺點(diǎn)。例如:

由于LTAF將待測試的頁面放置在Frame中,因此該頁面上的window.top等基于瀏覽器frame結(jié)構(gòu)的屬性會被改變。

由于LTAF的本質(zhì)是使用JavaScript來操作DOM,這意味著任何會阻塞程序進(jìn)行的操作(例如alert)都不能使用,否則將阻塞整個測試過程。

不過幸運(yùn)的是,這兩點(diǎn)都不回成為嚴(yán)重的問題。對于第一種,我們只需要編寫一個自定的getTop方法來替換直接訪問windows.top的做法即可。而第二種情況——老趙從來不喜歡alert或confirm這種“純?yōu)g覽器功能”,因?yàn)樗鼈儠䦷砗懿畹挠脩趔w驗(yàn),更何況現(xiàn)在的JavaScript類庫/框架都能很輕松的做出這種效果,您覺得呢?

LTAF的具體使用方式可參考其Release Note。令人奇怪的是,老趙發(fā)現(xiàn)直接在項(xiàng)目中使用LTAF會有一些小問題(不過它的示例為什么就一切正常呢?),因此進(jìn)行了一些細(xì)微的修改。請注意~\UnitView\DriverPage.aspx文件尾部的一些JavaScript代碼。

UnitView的使用

于是老趙編寫了一個組件UnitView,方便我們構(gòu)造一個單元測試時所需的數(shù)據(jù)。有了數(shù)據(jù),便能夠直接將視圖在瀏覽器中加以呈現(xiàn)了。例如:

[WebTestClass]

public class HomeTests

{

[WebTestMethod]

public void LoggedOnIndexTest()

{

var data = new TestViewData

{

ControllerName = "Home",

ActionName = "Index",

Model = new IndexModel

{

Message = "Welcome guys!",

Identity = new UserIdentity

{

IsAuthenticated = true,

Name = "Jeffrey Zhao"

}

}

};

HtmlPage page = new HtmlPage(TestViewData.GenerateHostUrl(data));

// Assert title

Assert.AreEqual("Home Page", page.Elements.Find("title", 0).GetInnerText());

// Assert head element

var mainContent = page.Elements.Find("main");

var head2 = mainContent.ChildElements.FindAll("h2").Single();

Assert.AreEqual(data.Model.Message, head2.GetInnerText(), "Message should be displayed.");

var loginTabInnerText = page.Elements.Find("logindisplay").GetInnerTextRecursively();

Assert.IsTrue(loginTabInnerText.Contains("Welcome"), "'Welcome' missed.");

Assert.IsTrue(loginTabInnerText.Contains(data.Model.Identity.Name), "Login name missed.");

}

}

自然,Web Server是不可或缺的。幸運(yùn)的是,分離讓我們的視圖只會涉及最簡單的測試數(shù)據(jù),這樣VS自帶的簡單Web Server就足夠了。在上面的代碼中,我們直接構(gòu)造了強(qiáng)類型的TestViewData對象,它包含呈現(xiàn)一個視圖所需要的所有數(shù)據(jù):

Cotroller和Action名稱。從理論上說,由不同的Controller和Action進(jìn)入同樣的視圖可能會得到不同的結(jié)果。

View和Master名稱。如果省略,則表明將使用默認(rèn)的視圖,即通過Controller和Action的值來確定。

ViewData和Model。

TestViewData.GenerateHostUrl方法會把data保存起來,并返回一個URL。訪問該URL便能夠得到對應(yīng)的視圖內(nèi)容。

如果您想使用UnitView,可以從上面的鏈接中下載UnitView的源代碼和示例在本機(jī)進(jìn)行嘗試。使用UnitView時主要有以下幾個注意點(diǎn):

將Tests項(xiàng)目的輸出路徑指向被測試網(wǎng)站的bin目錄,這樣既可以在運(yùn)行時得到正確的程序集,又不必為網(wǎng)站添加多余的引用。
將~\UnitView目錄復(fù)制到您的網(wǎng)站根目錄下(在發(fā)布網(wǎng)站時,請?zhí)蕹撃夸洠�。如果想使用其它目錄,請關(guān)注接下來UnitView實(shí)現(xiàn)分析。
編輯~\UnitView\Web.config文件,將MvcApp.Tests.dll修改為您自己的包含測試代碼的程序集。

UnitView實(shí)現(xiàn)分析

UnitView組件非常簡單,簡單地幾乎不值一提。TestViewData類型包含了測試需要的所有數(shù)據(jù),而TestViewData繼承了TestViewData,提供了強(qiáng)類型的Model屬性訪問方式。它們就不作分析了。

分享:ASP.NET如何防止用戶多次登錄
常見的處理方法是,在用戶登錄時,判斷此用戶是否已經(jīng)在Application中存在,如果存在就報(bào)錯,不存在的話就加到Application中(Application是所有Session共有的,整個web應(yīng)用程序唯一的一個對象): 以下是引用片段: string strUserId = txtUser.Text; ArrayLi

共2頁上一頁12下一頁
來源:模板無憂//所屬分類:.Net教程/更新時間:2009-05-16
相關(guān).Net教程