easymock教程-運(yùn)行時(shí)返回值或者異常
前面的教程中,我們看到easymock可以通過expect方法來(lái)設(shè)定mock方法的返回值或者異常,但是注意這些案例中設(shè)置的返回值都是在調(diào)用被測(cè)試的類的方法前就已經(jīng)確定下來(lái)的,即我們其實(shí)在測(cè)試類的代碼運(yùn)行前(實(shí)際是在EasyMock.replay()方法調(diào)用前)就已經(jīng)"預(yù)知"了返回結(jié)果。
但是在某些情況下,我們可能無(wú)法預(yù)知返回值,比如我們需要根據(jù)輸入的參數(shù)值來(lái)決定返回什么,而這個(gè)參數(shù)可能無(wú)法在record階段獲得。因此在mock方法中我們無(wú)法在record階段就決定應(yīng)該返回什么。
對(duì)于這種場(chǎng)景,easymock提供了IAnswer接口和andAnswer()方法來(lái)提供運(yùn)行時(shí)決定返回值或者異常的機(jī)制。
我們來(lái)看一個(gè)簡(jiǎn)單的例子:





















在Business的execute()方法中,需要調(diào)用service.execute(int count)方法,而傳入的參數(shù)count是需要運(yùn)行時(shí)才能確定的,這里為了簡(jiǎn)單我們r(jià)andom了一個(gè)int來(lái)模擬這種情況。
然后看測(cè)試案例
















這里我們通過EasyMock.expect(service.execute(EasyMock.anyInt()))來(lái)接受任意值的count參數(shù)輸入,andAnswer(new IAnswer<Integer>() {}) 讓我們可以指定一個(gè)IAnswer的實(shí)現(xiàn)類來(lái)給出返回值。在這個(gè)IAnswer的實(shí)現(xiàn)類中,我們通過EasyMock.getCurrentArguments()[0]獲取到service.execute()方法的第一個(gè)參數(shù),然后簡(jiǎn)單的運(yùn)用count*2規(guī)則給出返回值。這里的EasyMock.getCurrentArguments()方法可以獲取到運(yùn)行時(shí)的參數(shù)列表,不過注意這個(gè)方法對(duì)重構(gòu)不夠友好,如果參數(shù)列表發(fā)生變化則必須手工修改對(duì)象的獲取參數(shù)的代碼。
下面是一個(gè)運(yùn)行時(shí)拋出異常的例子,簡(jiǎn)單起見我們通過設(shè)置exception的message來(lái)在錯(cuò)誤信息中傳遞運(yùn)行時(shí)的count值。






















除了IAnswer接口外,easymock中還有另外一個(gè)方式可以完成類似的功能,就是使用andDelegate()方法,

















這里需要先創(chuàng)建一個(gè)Service類的實(shí)現(xiàn)類和一個(gè)實(shí)例,然后通過andDelegateTo()將這個(gè)stub的實(shí)例傳進(jìn)去,注意這里delegate進(jìn)去的實(shí)例必須是mock對(duì)象接口相同。
delegateTo方式實(shí)際上是我們手工創(chuàng)建了stub(mock和stub的概念及差別請(qǐng)參考本教程的"mock和stub"一文),這和我們使用easymock的初衷有所違背。而且當(dāng)這個(gè)接口有眾多方法時(shí),創(chuàng)建這樣一個(gè)stub會(huì)顯得很痛苦,不如使用IAnswer方便直接。
posted on 2010-11-30 16:36 sky ao 閱讀(3622) 評(píng)論(0) 編輯 收藏 所屬分類: software test