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

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

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

    Sky's blog

    我和我追逐的夢

    常用鏈接

    統計

    其他鏈接

    友情鏈接

    最新評論

    easymock教程-strict和nice

        在easymock的使用過程中,當創建mock對象時,我們會遇到 strict mock和nice mock的概念。

        比如創建mock對象我們通常使用EasyMock.createMock(),但是我們會發現easymock同時提供了兩個類似的方法:

     EasyMock.createNiceMock()
     EasyMock.createStrictMock()

        類似的在創建MocksControl時,除了通常的EasyMock.createControl() 外,easymock也同時提供兩個類似的方法:

     EasyMock.createNiceControl() 
     EasyMock.createStrictControl() 

        我們來看看strict和nice有什么作用。參考easymock的javadoc,我們對比createMock()和createStrictMock():
     EasyMock.createMock():          Creates a mock object that implements the given interface, order checking is disabled by default.
     EasyMock.createNiceMock() : Creates a mock object that implements the given interface, order checking is enabled by default.

        發現strict mock方式下默認是開啟調用順序檢測的,而普通的mock方式則默認不開啟調用順序檢測。

        再看一下createNiceMock():

    Creates a mock object that implements the given interface, order checking is disabled by default, and the mock object will return 0, null or false for unexpected invocations.

        和createMock()相同的是默認不開啟調用順序檢測,另外有一個非常有用的功能就是對于意料之外的調用將返回0,null 或者false.之所以說有用,是因為在我們的實際開發過程中,有時候會有這樣的需求:對于某個mock對象的調用(可以是部分,也可以是全部),我們完全不介意調用細節,包括是否調用和調用順序,參數,返回值,我們只要求mock對象容許程序可以繼續而不是拋出異常報告說 unexpected invocations 。nice mock在這種情況下可以為我們節省大量的工作量,非常方便。

        我們來看一個簡單的實際使用的例子,假設我們有一個Business類,依賴于兩個service 接口:

        先看只調用一個依賴的情況,注意在record階段service1.method2()和service1.method1()的順序和business.executeService1()方法中的實際調用順序是故意設置為不同的。

        public class Business {
            
    private Service1 service1;

            
    private Service2 service2;
            
            
    public void executeService1() {
                service1.method1();
                service1.method2();
            }

            
            
    public void executeService1And2() {
                service1.method1();
                service1.method2();
                
                service2.method3();
                service2.method4();
            }


            
    public void setService1(Service1 service1) {
                
    this.service1 = service1;
            }


            
    public void setService2(Service2 service2) {
                
    this.service2 = service2;
            }

        }


        
    private interface Service1 {

            
    public void method1();

            
    public void method2();
        }


        
    private interface Service2 {

            
    public void method3();

            
    public void method4();
        }


    1. 普通mock

        @Test
        
    public void testMock() {
            Business business 
    = new Business();
            Service1 service1 
    = EasyMock.createMock("service1", Service1.class);
            business.setService1(service1);
            
            service1.method2();
            EasyMock.expectLastCall();
            service1.method1();
            EasyMock.expectLastCall();

            
            EasyMock.replay(service1);
            business.executeService1();
            EasyMock.verify(service1);
        }


        測試案例可以通過,說明EasyMock.createMock()的確是不檢測方法的調用順序。

    2. strict mock

        @Test
        
    public void testStrictMock() {
            Business business 
    = new Business();
            Service1 service1 
    = EasyMock.createStrictMock("service1", Service1.class);
            ...
        }


        案例失敗,錯誤信息如下
    java.lang.AssertionError:
      Unexpected method call service1.method1():
        service1.method2(): expected: 1, actual: 0
     at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
     at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
     at net.sourcesky.study.easymock.tutorial.$Proxy4.method1(Unknown Source)
     at net.sourcesky.study.easymock.tutorial.OrderTest$Business.executeService1(OrderTest.java:14)
     at net.sourcesky.study.easymock.tutorial.OrderTest.testStrictMock(OrderTest.java:79)
     ......

        說明strict mock下,easymock檢測到了實際調用時的順序和預期的不同。

    3. nick mock

        @Test
        
    public void testNiceMock() {
            Business business 
    = new Business();
            Service1 service1 
    = EasyMock.createNiceMock("service1", Service1.class);
            ...
        }

        測試案例可以通過,而且如果是nick mock的話,record階段可以簡化:

        @Test
        
    public void testNiceMockSimplify() {
            Business business 
    = new Business();
            Service1 service1 
    = EasyMock.createNiceMock("service1", Service1.class);
            business.setService1(service1);
            
            EasyMock.replay(service1);
            business.executeService1();
            EasyMock.verify(service1);
        }

        這個簡化版本的測試案例也是可以通過的。

        上述的測試案例驗證了strict mock和nice mock的基本使用,對于同一個mock對象,strict模式下多個方法之間的調用順序在record階段和replay階段下是需要保持一致的。但是故事并不是到此結束,更有意思的內容在后面:如果出現多個mock對象,那么這些不同mock對象的方法之間,他們的調用順序是否檢測?普通mock和nice mock模式下自然是不會檢測順序,但是strict模式下呢?

        我們來看需要測試的方法executeService1And2(),這個方法會依次調用service1和service2的方法。使用easymock測試這個方法,注意我們在record階段依然故意將方法的調用順序設置為和實際不同。

    1. 不使用control,直接創建兩個strict mock對象

        @Test
        
    public void testWithoutControlInWrongOrder() {
            Business business 
    = new Business();
            Service1 service1 
    = EasyMock.createStrictMock("service1", Service1.class);
            Service2 service2 
    = EasyMock.createStrictMock("service2", Service2.class);
            business.setService1(service1);
            business.setService2(service2);
            
            service2.method3();
            EasyMock.expectLastCall();
            service1.method1();
            EasyMock.expectLastCall();
            
            EasyMock.replay(service1, service2);
            business.executeService1And2();
            EasyMock.verify(service1, service2);
        }

        這個測試案例,出于意外的,通過了。easymock并沒有檢測service1.method1()和service2.method3()這兩個方法的調用順序。


    2. 使用strict control創建兩個strict mock對象

        @Test
        
    public void testWithStrictControlInWrongOrder() {
            Business business 
    = new Business();
            IMocksControl mocksControl 
    = EasyMock.createStrictControl();
            ...
        }

        案例失敗,錯誤信息為:

    java.lang.AssertionError:
      Unexpected method call service1.method1():
        service2.method3(): expected: 1, actual: 0
     at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
     at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
     at net.sourcesky.study.easymock.tutorial.$Proxy4.method1(Unknown Source)
     at net.sourcesky.study.easymock.tutorial.OrderTest$Business.executeService1And2(OrderTest.java:19)
     at net.sourcesky.study.easymock.tutorial.OrderTest.testWithStrictControlInWrongOrder(OrderTest.java:218)
     ......

        OK,easymock終于檢測到service1.method1()和service2.method3()這兩個方法的調用順序和期望的不一致了。

        解釋一下,EasyMock.createStrictMock()方法實際上內部是生成一個新的strict control,然后再創建mock對象。

            Service1 service1 = EasyMock.createStrictMock("service1", Service1.class);
            Service2 service2 = EasyMock.createStrictMock("service2", Service2.class);

        這里實際是創建了兩個strict control,而easymock是不會跨control進行順序檢測的。在實際使用過程中,我們會有大量的場景需要檢測多個mock之間的調用順序(按說如果沒有特殊要求,一般的測試場景默認都應該如此),這種情況下就必須使用control, 而且必須是同一個strict control才能滿足要求。

        教程后面的最佳實踐中有一條就是推薦使用mock control,可以跨mock對象檢測方法調用順序是一個重要原因。

     

     

    posted on 2010-11-19 11:39 sky ao 閱讀(2622) 評論(0)  編輯  收藏 所屬分類: software test

    主站蜘蛛池模板: 国产免费丝袜调教视频| 亚洲精品成a人在线观看| 福利片免费一区二区三区| 久久久久亚洲AV成人网人人网站 | 亚洲手机中文字幕| 国产色爽免费视频| 男女午夜24式免费视频 | 中国一级毛片视频免费看| 亚洲精品视频在线播放| 婷婷亚洲天堂影院| 又黄又爽又成人免费视频| aa午夜免费剧场| 国产精品亚洲精品观看不卡| 中文字幕精品亚洲无线码一区| 黄色网址免费观看| 中国毛片免费观看| 国产成人精品日本亚洲语音| 久久亚洲国产精品五月天| 无码专区一va亚洲v专区在线| 亚洲人成免费网站| 中文字幕视频在线免费观看| 亚洲乱妇熟女爽到高潮的片| 亚洲自偷自偷精品| 在线播放亚洲第一字幕| 在线日韩av永久免费观看| 16女性下面扒开无遮挡免费| 国产成人1024精品免费| 亚洲s码欧洲m码吹潮| 亚洲国产精品久久丫| 亚洲AV无码乱码在线观看裸奔 | 亚洲综合网站色欲色欲| 永久免费无码网站在线观看| 国产成人免费在线| 日韩精品在线免费观看| fc2成年免费共享视频18| 国产亚洲福利一区二区免费看 | 2019中文字幕免费电影在线播放| 久久毛片免费看一区二区三区| 亚洲AV综合色区无码一二三区| 亚洲精品国产福利片| 亚洲高清在线观看|