亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        ASP.NET WebForms項目單元測試方法設計

        2014-03-24 12:47:06董寧
        電子設計工程 2014年6期
        關鍵詞:頁面

        董寧

        (武漢軟件工程職業(yè)學院 湖北 武漢 430205)

        ASP.NET WebForms是2002年作為.NET平臺的一部分發(fā)布的,它的發(fā)布對全世界的開發(fā)人員,是一個重要的里程碑。ASP.NET WebForms這一開發(fā)框架能夠讓我們使用C#語言和Visual Studio.NET環(huán)境開發(fā)強大的Web應用程序。ASP.NET WebForms框架的優(yōu)勢是可以讓我們利用內(nèi)置控件快速開發(fā)Web應用程序,它所提供的控件可以實現(xiàn)數(shù)據(jù)庫數(shù)據(jù)的編輯、刪除與格式化顯示和成員管理等幾乎全部的常用Web應用程序功能。

        在使用ASP.NET WebForms框架開發(fā)Web應用程序時,開發(fā)人員主要的工作就是將控件拖放到頁面上,然后發(fā)布網(wǎng)站。這種開發(fā)模式可以快速的生成Web應用程序,但并沒有考慮應用程序的體系結構和可測試性。開發(fā)人員很快發(fā)現(xiàn),隨著項目需求的不斷增長,用ASP.NET WebForms框架開發(fā)項目會面臨一系列嚴重問題。問題之一就是我們無法有效的對ASP.NET WebForms項目代碼進行單元測試[1]。

        本文將重點探討如何在ASP.NET WebForms項目中使用單元測試。

        1 ASP.NET WebForms項目單元測試原理

        一個典型ASP.NET WebForms應用程序由兩個主要部分組成。一是后綴名為aspx的頁面文件,由ASP.NET標記編寫而成,這種標記混合了HTML和ASP.NET控件,并且包含了在服務器上執(zhí)行的C#程序代碼。第二部分是與aspx頁面文件對應的后綴名為aspx.cs的后臺代碼文件,這些文件由C#代碼編寫而成,用以支持頁面文件并與頁面生命周期[2]掛鉤,這些代碼在頁面加載時和頁面響應用戶請求時在服務器上執(zhí)行。

        由于后綴名為aspx.cs的后臺代碼文件與頁面生命周期掛鉤,因此它們的執(zhí)行緊密依賴于ASP.NET核心運行庫。在進行測試時,這種依賴會導致大量問題,例如在編寫單元測試時,將嘗試在ASP.NET運行庫環(huán)境外執(zhí)行代碼,這樣會導致出現(xiàn)大量的ASP.NET運行庫相關錯誤消息。而對于后綴名為aspx的頁面文件,頁面文件中的任何代碼都是不能被其它類所訪問的,因此將無法為其編寫任何單元測試。同時,ASP.NET WebForms框架還無法讓頁面保持輕量級,因為頁面當中往往會包含大量的控件[3],如下面給出的這個GridView控件示例:

        <asp:GridView ID="grd1"runat="server"DataSourceID="obj1"

        AutoGenerateColumns="false"

        AllowPaging="true">

        <Columns>

        <asp:CommandField ShowSelectButton="true"/>

        <asp:BoundField DataField="Name"HeaderText="

        姓名"

        SortExpression="Name"/>

        </Columns>

        </asp:GridView>

        上述類型的代碼會讓頁面文件變得凌亂,同時由頁面文件在服務器端運行生成的HTML代碼也會過于復雜。如果按這種方式開發(fā)ASP.NET WebForms項目,則意味無法清晰的分割代碼,導致沒有可行的方式來編寫單元測試,甚至進行自動化的用戶界面測試都是很困難的。

        為了能夠在ASP.NET WebForms項目中使用單元測試,我們應該以一種不同的方式來開發(fā)應用程序,要讓頁面文件和后臺代碼盡可能地“瘦”,也就是說它們應當盡量不包含實際頁面邏輯代碼,而是將頁面邏輯代碼放到一個單獨的類中。雖然ASP.NETWebForms框架的默認開發(fā)方式鼓勵在后臺代碼文件中編寫頁面邏輯代碼,但這并不符合單元測試的要求。我們應該用一種頁面和后臺代碼盡可能清晰簡潔的方式來開發(fā)ASP.NET WebForms項目,最可行的方法就是在項目開發(fā)時遵循 MVP(Model-View-Presenter)設計模式[4-5]。

        當遵循MVP模式開發(fā)ASP.NET WebForms項目時,與常規(guī)開發(fā)方式最大的不同就是將后臺代碼中所有的頁面邏輯轉移到一個單獨的類之中,然后通過一個定義了頁面行為的特定接口讓頁面邏輯類與頁面聯(lián)系起來。遵循MVP模式開發(fā)的ASP.NET WebForms項目讓我們可以清晰的分割ASP.NET WebForms框架代碼和頁面邏輯代碼,只有這樣我們才能為項目添加可行的單元測試代碼。

        2 ASP.NET WebForms項目開發(fā)模式設計

        假設現(xiàn)在有一個ASP.NETWebForms頁面需要開發(fā)并編寫單元測試代碼,這個頁面中包含兩個控件,按鈕(Button)和列表框(ListBox),頁面要實現(xiàn)的具體功能是當用戶單擊按鈕時向服務器請求數(shù)據(jù)并在列表框中顯示數(shù)據(jù)。

        遵循MVP設計模式不難發(fā)現(xiàn),該頁面的具體功能可以通過一個接口抽象出來。該接口需要定義一個請求服務器數(shù)據(jù)的事件以便頁面調(diào)用,同時還需要一個存儲數(shù)據(jù)的屬性和一個讓頁面更新和顯示這一數(shù)據(jù)的方法。接口定義代碼如下:

        public interface IMainView{

        event EventHandler DataRequest;

        List<string> Data{set; get; }

        void Bind();

        }

        接下來,讓頁面對象實現(xiàn)該接口,這樣我們就可以在單獨的類里實現(xiàn)該接口,并將類實例傳遞給頁面,具體頁面代碼如下:

        public partial class _Default:System.Web.UI.Page,IMainView{

        public event EventHandler DataRequest;

        public List<string> Data{get; set; }

        private MainController Controller;

        protected void Page_Load(object sender, EventArgs e){

        Controller=new MainController(this);

        }

        public void Bind(){

        ListBox1.DataSource=Data;

        ListBox1.DataBind();

        }

        protected void Button1_Click(object sender, EventArgs e)

        {

        if(DataRequest!=null)

        DataRequest(sender, e);

        } }

        在頁面代碼中,名為MainController的類充當了MVP設計模式中控制器的角色,頁面類在初始化時,將自身的實例發(fā)送給了控制器,而控制器存儲這一頁面類實例用于之后的方法調(diào)用。

        MainController類在初始化時必須與頁面所需的所有事件掛鉤,并將它們關聯(lián)到恰當?shù)姆椒ㄉ希源_保正確實現(xiàn)頁面功能。MainController類實現(xiàn)如下:

        public class MainController{

        public IMainView View{get; set; }

        public MainController(IMainView view) {

        View=view;

        View.DataRequest+=GetData;

        }

        public void GetData(object sender,EventArgs e) {

        View.Data=new List<string>{

        對于商場來說,其競爭力的體現(xiàn)通常為兩個方面,即服務質(zhì)量和商品更新的速度。商場的經(jīng)濟效益受很多方面的影響,其中室內(nèi)環(huán)境是最為重要的影響因素。若環(huán)境舒適,能最大程度地激起顧客的消費欲望。商品銷售速度加快,競爭力得以提升。室內(nèi)設計是競爭力提升的基礎保障,商場效益提升是環(huán)境設計的直接體現(xiàn),兩者相輔相成,缺一不可。圖1是某商場的內(nèi)部結構圖,僅供參考。

        "張三","李四","王五","趙六"

        };

        View.Bind();

        }

        }

        MainController類通過GetData方法實現(xiàn)了獲取服務器數(shù)據(jù)的功能(本文不涉及數(shù)據(jù)處理,所以數(shù)據(jù)直接給出),并通過DataRequest事件將此功能與頁面掛鉤。控制器類的所有代碼都是獨立于ASP.NET生命周期存在的,所以能夠很方便的對其編寫單元測試來驗證功能是否正確。由于MainController類包含了幾乎全部的頁面頁面邏輯代碼,如果能夠通過單元測試確保MainController類的正確性,也就能保證整個頁面功能的正確性。

        3 實現(xiàn)ASP.NET WebForms項目單元測試

        實現(xiàn)對ASP.NET WebForms項目的單元測試,主要就是實現(xiàn)對WebForms頁面的單元測試。遵循上一節(jié)所提到的MVP開發(fā)模式編寫ASP.NET WebForms項目頁面,可以讓全部的頁面邏輯實現(xiàn)代碼集中到一個獨立于ASP.NET生命周期存在的類當中,也就是說,如果我們能夠編寫單元測試代碼檢測頁面邏輯類與頁面是否正確連接和檢測頁面邏輯相關代碼是否正確執(zhí)行的話,也就相當于完成了對整個頁面的單元測試。

        [TestClass]

        public class MainControllerTests{

        [TestMethod]

        public void CtorIsHookupEvents(){

        IMainView view = MockRepository.GenerateMock <IMainView>();

        view.Expect (view => view.DataRequested += null).IgnoreArguments();

        new MainController(view);

        view.VerifyAllExpectations();

        }

        }

        上述代碼使用了RhinoMocks測試框架,該框架可以根據(jù)IMainView接口模擬出視圖實例用于測試。這一部分重點測試了試圖實例被傳遞給MainController類后其中的DataRequested事件是否關聯(lián)了[3,4]程序,也就是被執(zhí)行了“+=”操作。

        在對事件實現(xiàn)單元測試后,下一步就是測試在事件發(fā)生時被調(diào)用的GetData方法。GetData方法的作用是在被調(diào)用時填充視圖中的Data屬性。同樣的,在測試時還是利用RhinoMocks測試框架,根據(jù)IMainView接口模擬出視圖實例,然后根據(jù)該實例創(chuàng)建出頁面邏輯類實例,也就是MainController類實例,就好像是一個真正的頁面在運行一樣。接下來直接調(diào)用GetData方法,然后檢測Data屬性是否被正確填充。具體的單元測試代碼如下:

        [TestMethod()]

        public void GetDataIsPopulateData(){

        IMainView view = MockRepository.GenerateStub <IMainView>();

        MainController controller=new MainController(view);

        controller.GetData(this, EventArgs.Empty);

        Assert.AreEqual(4, view.Data.Count);

        }

        如果頁面邏輯類在調(diào)用GetData方法后正確填充了Data屬性,那么上述測試將正確通過,否則單元測試測試會失敗。

        對于ASP.NET WebForms頁面來說,在獲取數(shù)據(jù)后需要通知視圖來刷新用戶界面并向用戶顯示數(shù)據(jù),所以最后要測試的部分就是確保頁面邏輯類能夠正確調(diào)用頁面視圖類中的Bind方法。在這里同樣可以使用RhinoMocks測試框架創(chuàng)建出一個模擬的MainController類實例,來驗證調(diào)用GetData方法后Bind方法也會被正確調(diào)用。具體代碼如下:

        [TestMethod()]

        public void GetDataIsCallBind(){

        IMainView view = MockRepository.GenerateMock <IMainView>();

        view.Expect(v=> v.Bind());

        MainController controller=new MainController(view);

        controller.GetData(this, EventArgs.Empty);

        view.VerifyAllExpectations();

        }

        至此,可以說完全實現(xiàn)了對上節(jié)ASP.NET WebForms項目頁面代碼的單元測試。

        4 結束語

        雖然遵循MVP模式開發(fā)ASP.NET WebForms項目可以提高代碼的可測試性并實現(xiàn)WebForms頁面的單元測試,但這種方法并不完美。因為ASP.NET WebForms本身的架構決定了不可能能將100%的項目代碼都納入到單元測試中來。比如上節(jié)例子中的兩個函數(shù)就無法被包含到單元測試中,其代碼如下:

        public void Bind(){

        ListBox1.DataSource=Data;

        ListBox1.DataBind();

        }

        protected void Button1_Click(object sender, EventArgs e)

        {

        if(DataRequest!=null)

        DataRequest(sender, e);

        }

        盡管上述兩個方法不經(jīng)測試也不會引起大問題,但不難想象,隨著項目的增長,這種未經(jīng)測試的代碼也會增加,從而增加錯誤代碼被引入到項目中的可能性。

        所以,除非是對現(xiàn)有項目進行重構,一般不建議用MVP模式開發(fā)ASP.NET WebForms項目。其實MVP模式也并不是為ASP.NET WebForms項目開發(fā)的主流方法,它會增加項目的復雜性,而且微軟官方對該模式也沒有提供支持。如果需要利用ASP.NET開發(fā)可測試性高的Web項目,還是建議選用微軟新發(fā)布的的基于MVC模式的Web開發(fā)框架,稱為ASP.NET MVC[6],該框架在可測試性支持方面比ASP.NET WebForms框架好很多。

        [1]張旭,王鵬,習媛媛,等.單元測試在軟件質(zhì)量保證中的應用研究[J].煤炭技術,2010,29(6):185-186.ZHANG Xu,WANG Peng,XI Yuan-yuan,et al.Application of unittestingtosoftwarequality assurance[J].Coal Technology,2010,29(6):185-186.

        [2]江艷萍.深入淺出ASP.NET頁面對象模型 [J].電腦知識與技術,2007, 2(11):1314-1315.JIANG Yan-ping.Understanding asp.net page object model in a simple way[J].Computer Knowledge and Technology,2007,2(11):1314-1315.

        [3]馬潔,周靜.基于ASP.NET控件定義的分析與比較[J].通信技術,2010,43(4):144-146.MA Jie,ZHOU Jing.Analysis and comparion of the control definition based on asp.net[J].Communications Technology,2010,43(4):144-146.

        [4]顧明霞,蔡長安.WebForms、MVC和MVP在ASP.NET開發(fā)中的對比分析[J].重慶工商大學學報:自然科學版,2011,28(4):394-397,409.GUMing-xia,CAIChang-an.Comparativeanalysisof webforms,MVC and MVP architecture in asp.net development[J].Journal of Chongqing Technology and Business:Natural Sciences Edition,2011,28(4):394-397,409.

        [5]劉海巖,鎖志海,呂青,等.設計模式及其在軟件設計中的應用研究[J].西安交通大學學報,2005,39(10):1043-1047.LIU Hai-yan,SUO Zhi-hai,LV Qing,et al.Design patterns and their applications to software design[J].Journal of Xi'an Jiaotong University,2005, 39(10):1043-1047.

        [6]陳曉丹,鄭毅.ASP.NET開發(fā)環(huán)境下的WebForm與MVC設計模式[J].武漢工程職業(yè)技術學院學報,2009,21(2):38-40,34.CHEN Xiao-dan,ZHENG Yi.Comparison of ASP webform and MVC[J].Journal of Wuhan Engineering Institute,2009,21(2):38-40,34.

        猜你喜歡
        頁面
        微信群聊總是找不到,打開這個開關就好了
        大狗熊在睡覺
        刷新生活的頁面
        在本機中輕松完成常見PDF操作
        電腦愛好者(2022年3期)2022-05-30 10:48:04
        移動頁面設計:為老人做設計
        Web安全問答(3)
        通信技術(2012年4期)2012-02-15 07:10:35
        同一Word文檔 縱橫頁面并存
        網(wǎng)站結構在SEO中的研究與應用
        幾種頁面置換算法的基本原理及實現(xiàn)方法
        淺析ASP.NET頁面導航技術
        国产日产韩国级片网站| 亚洲国产成人AV人片久久网站 | 国产成人无码av一区二区| 亚洲av成本人无码网站| 人妻无码AⅤ中文系列久久免费| 亚洲性日韩一区二区三区| 久久久久亚洲av成人网人人软件| 国产精品jizz在线观看老狼| 神马不卡一区二区三级| 水蜜桃在线观看一区二区国产| 午夜无码一区二区三区在线观看| 国产精品熟女一区二区| 美女污污网站| 亚洲二区精品婷婷久久精品| 色欲av永久无码精品无码蜜桃 | 亚洲香蕉视频| 国产成人午夜av影院| 日本中文一区二区在线| 少妇无码av无码一区| 久久无码精品精品古装毛片| 免费人成网站在线播放| 欧美精品色婷婷五月综合| 欧妇女乱妇女乱视频| 91精品国产91| 精品国产中文久久久免费| 三年片免费观看影视大全视频| 久久久精品波多野结衣| 亚洲成a人片77777kkkkk| 亚洲av专区国产一区| 亚洲av无码一区二区乱孑伦as| 97国产免费全部免费观看| 无码人妻一区二区三区免费n鬼沢| 国产亚洲女人久久久久久| 亚洲av成人一区二区| 亚洲伊人一本大道中文字幕| 美日韩毛片| 五月激情在线观看视频| 欧美老熟妇乱xxxxx| a一区二区三区乱码在线 | 欧洲| 日本高清中文一区二区三区| 亚洲精品国产第一综合色吧|