easymock教程-strict和nice
在easymock的使用過(guò)程中,當(dāng)創(chuàng)建mock對(duì)象時(shí),我們會(huì)遇到 strict mock和nice mock的概念。
比如創(chuàng)建mock對(duì)象我們通常使用EasyMock.createMock(),但是我們會(huì)發(fā)現(xiàn)easymock同時(shí)提供了兩個(gè)類似的方法:


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


我們來(lái)看看strict和nice有什么作用。參考easymock的javadoc,我們對(duì)比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.
發(fā)現(xiàn)strict mock方式下默認(rèn)是開(kāi)啟調(diào)用順序檢測(cè)的,而普通的mock方式則默認(rèn)不開(kāi)啟調(diào)用順序檢測(cè)。
再看一下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()相同的是默認(rèn)不開(kāi)啟調(diào)用順序檢測(cè),另外有一個(gè)非常有用的功能就是對(duì)于意料之外的調(diào)用將返回0,null 或者false.之所以說(shuō)有用,是因?yàn)樵谖覀兊膶?shí)際開(kāi)發(fā)過(guò)程中,有時(shí)候會(huì)有這樣的需求:對(duì)于某個(gè)mock對(duì)象的調(diào)用(可以是部分,也可以是全部),我們完全不介意調(diào)用細(xì)節(jié),包括是否調(diào)用和調(diào)用順序,參數(shù),返回值,我們只要求mock對(duì)象容許程序可以繼續(xù)而不是拋出異常報(bào)告說(shuō) unexpected invocations 。nice mock在這種情況下可以為我們節(jié)省大量的工作量,非常方便。
我們來(lái)看一個(gè)簡(jiǎn)單的實(shí)際使用的例子,假設(shè)我們有一個(gè)Business類,依賴于兩個(gè)service 接口:
先看只調(diào)用一個(gè)依賴的情況,注意在record階段service1.method2()和service1.method1()的順序和business.executeService1()方法中的實(shí)際調(diào)用順序是故意設(shè)置為不同的。








































1. 普通mock

















測(cè)試案例可以通過(guò),說(shuō)明EasyMock.createMock()的確是不檢測(cè)方法的調(diào)用順序。
2. strict mock








案例失敗,錯(cuò)誤信息如下
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)
......
說(shuō)明strict mock下,easymock檢測(cè)到了實(shí)際調(diào)用時(shí)的順序和預(yù)期的不同。
3. nick mock






測(cè)試案例可以通過(guò),而且如果是nick mock的話,record階段可以簡(jiǎn)化:










這個(gè)簡(jiǎn)化版本的測(cè)試案例也是可以通過(guò)的。
上述的測(cè)試案例驗(yàn)證了strict mock和nice mock的基本使用,對(duì)于同一個(gè)mock對(duì)象,strict模式下多個(gè)方法之間的調(diào)用順序在record階段和replay階段下是需要保持一致的。但是故事并不是到此結(jié)束,更有意思的內(nèi)容在后面:如果出現(xiàn)多個(gè)mock對(duì)象,那么這些不同mock對(duì)象的方法之間,他們的調(diào)用順序是否檢測(cè)?普通mock和nice mock模式下自然是不會(huì)檢測(cè)順序,但是strict模式下呢?
我們來(lái)看需要測(cè)試的方法executeService1And2(),這個(gè)方法會(huì)依次調(diào)用service1和service2的方法。使用easymock測(cè)試這個(gè)方法,注意我們?cè)趓ecord階段依然故意將方法的調(diào)用順序設(shè)置為和實(shí)際不同。
1. 不使用control,直接創(chuàng)建兩個(gè)strict mock對(duì)象

















這個(gè)測(cè)試案例,出于意外的,通過(guò)了。easymock并沒(méi)有檢測(cè)service1.method1()和service2.method3()這兩個(gè)方法的調(diào)用順序。
2. 使用strict control創(chuàng)建兩個(gè)strict mock對(duì)象






案例失敗,錯(cuò)誤信息為:
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終于檢測(cè)到service1.method1()和service2.method3()這兩個(gè)方法的調(diào)用順序和期望的不一致了。
解釋一下,EasyMock.createStrictMock()方法實(shí)際上內(nèi)部是生成一個(gè)新的strict control,然后再創(chuàng)建mock對(duì)象。
Service1 service1 = EasyMock.createStrictMock("service1", Service1.class);
Service2 service2 = EasyMock.createStrictMock("service2", Service2.class);
這里實(shí)際是創(chuàng)建了兩個(gè)strict control,而easymock是不會(huì)跨control進(jìn)行順序檢測(cè)的。在實(shí)際使用過(guò)程中,我們會(huì)有大量的場(chǎng)景需要檢測(cè)多個(gè)mock之間的調(diào)用順序(按說(shuō)如果沒(méi)有特殊要求,一般的測(cè)試場(chǎng)景默認(rèn)都應(yīng)該如此),這種情況下就必須使用control, 而且必須是同一個(gè)strict control才能滿足要求。
教程后面的最佳實(shí)踐中有一條就是推薦使用mock control,可以跨mock對(duì)象檢測(cè)方法調(diào)用順序是一個(gè)重要原因。
posted on 2010-11-19 11:39 sky ao 閱讀(2627) 評(píng)論(0) 編輯 收藏 所屬分類: software test