<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

    手頭的項(xiàng)目越來越大,很多以前不會出現(xiàn)的問題開始浮現(xiàn)。

     

    比如:我修改了一個基礎(chǔ)的類庫,卻意外的影響了九重天外的客戶項(xiàng)目,直接導(dǎo)致一個功能無法實(shí)現(xiàn)。我郁悶啊!!!

     

    因此開始要有組織、有預(yù)謀、有計(jì)劃的對項(xiàng)目過程進(jìn)行測試驅(qū)動了。最終目標(biāo)是,我修改了底層某個dll的某個方法,測試框架能夠自動幫我找出來所有收到影響的類,全部執(zhí)行一次回歸測試,并發(fā)送一份漂亮的報告到我手里。

     

    這個目標(biāo)估計(jì)1、2個星期才能實(shí)現(xiàn),不過現(xiàn)在先放出一個非常漂亮的MOCK核心代碼。 

     

    研究過程

    在不斷收集各種資料過程中,學(xué)習(xí)了很多,例如以下關(guān)鍵字,有興趣的兄弟可以自己搜索一下:

     

    testdriven.net, nunit,  typemock, cruiseControl.net, Confluence, JIRE, NUnitForms, WatiN, MBUnit, CSUnit, NBehave, Gallio

    ranorex,  dynamicProxy...

     

    估計(jì)各位有時間看看上面的簡介,就能夠掌握現(xiàn)在測試驅(qū)動的大致發(fā)展。

     

    1. nunit的核心代碼非常容易理解,大伙自己下載看看就行了。
    2. testdriven.net 的前身是:NUnitAddin, 如果要研究如何testdriven集成到vs,看看不錯。
    3. WatiN的核心代碼雖然我沒有看,不過猜也能猜到,就是調(diào)用了IE的核,然后搜索上面的html標(biāo)簽操作。
    4. typeMock有點(diǎn)混蛋,源碼混淆了,無法拿到核心技術(shù),不過從介紹來看是源自了castle.DynamicProxy,那么各位可以參觀一下一篇非常垃圾的文章,但是起碼讓我入門了: http://www.cublog.cn/u/23701/showart_1414436.html
    5. 最后,我來到了Moq,開始因?yàn)槁犝f是.net3.5,就沒有看源碼,不過剛才研究了一下頓時非常興奮。起碼Moq能讓我解決了50%的工作。

     

    接下來就說下Mock技術(shù)和測試驅(qū)動中的作用。

     

    Mock技術(shù) 

    我最不喜歡老外造名詞,所以會用自己的體會去介紹。

    mock的本質(zhì)就是模擬目標(biāo)對象的一個假對象。 

    這個性質(zhì)在測試驅(qū)動中非常有用,例如我的代碼是:

    代碼
            public DateTime GetNextFiredDate(DateTime now, IOrmScheduleTrigger trigger, int triggeredtimes)
            {
                
    return GetNextFiredDate(now, trigger.TriggerType, trigger.TriggerExpression, triggeredtimes);
            }

     

     

     現(xiàn)在要測試這個代碼,就需要傳入一個IOrmScheduleTrrigger的接口對象。但是不幸的是,這個對象是個ORM,要啟動這個對象,就涉及到了數(shù)據(jù)庫。。。。

     

    老大,我只是想測試一下一輛寶馬的玻璃是否堅(jiān)硬,不需要啟動我的寶馬加速到120km,然后再用手去翹翹那塊玻璃吧。

     

    所以,我希望能夠有個模擬對象,繼承了這個接口, 同時提供了我期望的返回值,讓這個方法能夠順利執(zhí)行。

     

    傳統(tǒng)的傻逼方法,就是自己寫一個類,繼承了這個接口,然后才傳入進(jìn)去。例如:

     

    public class OrmScheduleTriggerTestObject : IOrmScheduleTrigger
    {
    // some method here
    }

     

     

    這樣不就更加的傻逼了?我為了測一塊玻璃,還親自造了另外一臺簡易的寶馬出來? 于是我開始翻閱各種文獻(xiàn),甚至考慮使用動態(tài)代理(DynamicProxy)。動態(tài)代理的核心思想就是在代碼運(yùn)行中寫IL生成一個繼承類。這個技術(shù)很有用,但是現(xiàn)在我還用不上(就像martin fowler說的,typemock就等于把核武器交給了一個4歲小孩)。

     

    于是我繼續(xù)尋找,終于翻開了Moq的源碼,找到了答案。

     

    先看看以下一段代碼,是我摘自Moq源碼的核心部分,稍加改造了:

     

    復(fù)制代碼
    代碼
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.Remoting.Proxies;
    using System.Runtime.Remoting.Messaging;

    namespace Pixysoft.Framework.TestDrivens
    {
        
    public class Mock<TInterface> : RealProxy
        {
            
    public Mock()
                : 
    base(typeof(TInterface))
            {
            }

            
    public TInterface Value
            {
                
    get
                {
                    
    return (TInterface)this.GetTransparentProxy();
                }
            }

            
    public override IMessage Invoke(IMessage msg)
            {
                IMethodCallMessage methodCall 
    = msg as IMethodCallMessage;

                
    //我返回int = 1

                
    return new ReturnMessage(1null0null, methodCall);
            }
        }

        
    public interface IMock
        {
            
    int Devide(int a, int b);
        }

        
    public class testrealproxy //測試代碼在這里!!!
        {
            
    public void test()
            {
                IMock mock 
    = new Mock<IMock>().Value;

                Console.WriteLine(mock.Devide(
    12));

                
    //輸出 = 1
            }
        }
    }
    復(fù)制代碼

     

     

    這段代碼就是Moq的核心思想。

     

    大概意思是:我希望調(diào)用接口IMock的方法Devide,但是我壓根不想寫這個接口的實(shí)現(xiàn)。

     

    那么我先寫一個通用的模擬對象Mock<TInterface>,繼承了RealProxy。

     

    然后通過調(diào)用Value就可以返回需要的接口對象。而這個對象就是 return (TInterface)this.GetTransparentProxy();是個透明代理。

     

    最后當(dāng)我調(diào)用了 int Devide(int a, int b); 方法的時候,等于調(diào)用了public override IMessage Invoke(IMessage msg)方法(有點(diǎn)點(diǎn)的AOP感覺)。

     

    后記

     

    上文就是Moq的核心思想了。非常的精彩!估計(jì)有了思路,各位就可以制造自己的原子彈了。

     

    這里插句題外話,很多人抨擊重復(fù)造輪子。我就奇怪了。如果我造一個輪子花費(fèi)的時間和學(xué)習(xí)用一個輪子的時間差不遠(yuǎn),為什么不造一個?

    而且,用別人的輪子,經(jīng)常出現(xiàn)的情況是:很多輪子不知道挑哪個。一旦挑上了,項(xiàng)目進(jìn)展到一般才發(fā)現(xiàn)不適合、有bug,于是又重頭挑另外的輪子。

     

    這個經(jīng)歷是真實(shí)的。當(dāng)年讀大學(xué),我的室友就是典型的挑輪子,他懂得很多框架(java),webwork,hibernate, spring。和人砍起來朗朗上口,但是需要深入做項(xiàng)目了,出現(xiàn)問題基本上不知所措,不是翻文獻(xiàn),就是問師兄,最后整個項(xiàng)目組從來就沒有一個成品。

     

    我自從學(xué)電腦依賴,從來就沒有用過別人的輪子,即使是hibernate,我的確也沒有用過,不過他的核心文檔倒是看過,對比之下,和oracle的toplink相比簡直就是小孩。

     

    比我牛逼的兄弟大有人在,希望各位牛人不要浪費(fèi)自己的時間去挑別人的輪子,直接自己造一個算了。 

     

    最后說說接下來的工作。

     

    基于接口的測試驅(qū)動完成了,剩下的就是面對sealed class 等頑固分子了, 必然需要動用非常規(guī)武器,DynamicProxy。下回再見。

     

     

    分享到:
    posted on 2013-04-20 15:29 abin 閱讀(492) 評論(0)  編輯  收藏 所屬分類: easyMock
    主站蜘蛛池模板: 亚洲欧美日韩综合久久久| 亚洲成AV人片在线观看WWW| 亚洲国产精品xo在线观看| 国产午夜精品理论片免费观看| 亚洲成a人片在线播放| 国产亚洲精品91| 免费在线观看亚洲| 青草青草视频2免费观看| 免费永久国产在线视频| 日韩大片免费观看视频播放| 免费国产在线观看| 一级毛片大全免费播放| 亚洲精品午夜无码专区| 无码国产精品一区二区免费3p | 亚洲a∨无码精品色午夜| 成人a视频片在线观看免费| 亚洲国产AV无码一区二区三区| 久久WWW免费人成人片| 一本天堂ⅴ无码亚洲道久久| 四虎在线视频免费观看| 在线观看亚洲专区| 亚洲色精品vr一区二区三区| 精品亚洲永久免费精品| 亚洲图片激情小说| 好爽好紧好大的免费视频国产| 日韩在线一区二区三区免费视频 | 亚洲国产精品日韩在线| 在线播放免费人成视频在线观看| 亚洲av色香蕉一区二区三区 | 国产午夜亚洲精品理论片不卡| 色播在线永久免费视频网站| 亚洲成人网在线观看| 在线观看免费大黄网站| 一级毛片a免费播放王色| 亚洲资源在线观看| 精品国产免费观看一区| 毛片基地看看成人免费| 亚洲国产日韩在线成人蜜芽 | 中文字幕日本人妻久久久免费| 亚洲欧洲国产成人精品| 丁香亚洲综合五月天婷婷|