EasyMock基本使用
我們的第一個(gè)例子非常簡單,但是在現(xiàn)實(shí)情況下,你通常是在一些類里使用另外的一些類。在進(jìn)行真正的測試之前,你可能需要做很多的工作,比喻說安置大量的環(huán)境代碼,啟動一種大型的、復(fù)雜的系統(tǒng),可能是數(shù)據(jù)庫、工作流或者是某一種類型的IDE環(huán)境,你的預(yù)設(shè)環(huán)境代碼需要是系統(tǒng)進(jìn)入某種特定的狀態(tài),以便按照測試所需要的方法進(jìn)行響應(yīng)。但是這種工作不大可能很快就能完成。
??為了對一部分類進(jìn)行單元測試,你需要建立和控制另外一些類。最好的辦法就是為需要測試的類創(chuàng)建一個(gè)模擬對象。你可以自己手工的編寫類,也可以使用EasyMock來產(chǎn)生這些對象。模擬對象提供了一種經(jīng)過證明是成功的解決方案。
??當(dāng)我們很難或不可能為某種難以處理的資源創(chuàng)建需要的狀態(tài)或者存取某種資源受限時(shí),你就可以使用模擬對象。
??模擬對象取代真實(shí)對象的位置,用于測試一些與真實(shí)對象進(jìn)行交互或依賴于真實(shí)對象的功能。模擬對象背后的基本思想就是創(chuàng)建輕量級的、可控制的對象來代替為了編寫測試為需要使用的對象。模擬對象還能夠讓你指定和測試你的代碼與模擬對象本身之間的交互。
說的再直白一點(diǎn),一個(gè)模擬對象就是一個(gè)簡單的接口或者是類,在里面你可以定義一個(gè)特定的方法調(diào)用之后的簡單的輸出。
?
使用Junit和Easy Mock
從EasyMock到主頁上下載EasyMock, 把下載得到的easymock.jar增加到你的classpath中。
創(chuàng)建一個(gè)Java工程JavaMockTest,創(chuàng)建下面的這些類。
IncomeCalculator是要被測試的類,這個(gè)類用來根據(jù)一個(gè)人的職位來計(jì)算一個(gè)人的工資的方法。?
?
package?income;public?enum?Position {BOSS, PROGRAMMER, SURFER}?
package?income.exceptions;
public?class?PositionException?extends?RuntimeException {
private?static?final?long?serialVersionUID = 1L;
public?PositionException(String message) {
super(message);
}?
package?income.exceptions;
public?class?CalcMethodException?extends?RuntimeException {
private?static?final?long?serialVersionUID = 1L;
public?CalcMethodException(String message) {
super(message);
}?
package?income.method;
import?income.Position;
public?interface?ICalcMethod {
public?abstract?double?calc(Position position);
}
package?income;
import?income.exceptions.CalcMethodException;
import?income.exceptions.PositionException;
import?income.method.ICalcMethod;
public?class?IncomeCalculator{
private?ICalcMethod calcMethod;
private?Position position;
public?void?setCalcMethod(ICalcMethod calcMethod){
this.calcMethod = calcMethod;
}
public?void?setPosition(Position position){
this.position = position;
public?double?calc (){
if?(calcMethod==null){
throw?new?CalcMethodException("CalcMethod not yet maintained");
}
if?(position==null){
throw?new?PositionException("Position not yet maintained");
}
return?calcMethod.calc(position);
}
?
使用Eclipse的JUnit功能為IncomeCalulator創(chuàng)建一個(gè)測試。在我的例子中,我同時(shí)創(chuàng)建一個(gè)新的源文件夾,名字為"test",我把我創(chuàng)建的測試類全部放到里面。
?下面就是一個(gè)使用EasyMock創(chuàng)建的測試。?
?
package?income;import?static?org.junit.Assert.assertEquals;
import?static?org.junit.Assert.fail;
import?income.exceptions.CalcMethodException;
import?income.exceptions.PositionException;
import?income.method.ICalcMethod;
import?org.easymock.EasyMock;
import?org.junit.Before;
import?org.junit.Test;?
public?class?IncomeCalculatorTest {?
private?ICalcMethod calcMethod;
private?IncomeCalculator calc;?
@Before
public?void?setUp()?throws?Exception {
calcMethod = EasyMock.createMock(ICalcMethod.class);
calc =?new?IncomeCalculator();
}
@Test
public?void?testCalc1() {
// Setting up the expected value of the method call calc
EasyMock.expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0).times(2);
EasyMock.expect(calcMethod.calc(Position.PROGRAMMER)).andReturn(50000.0);
// Setup is finished need to activate the mock
EasyMock.replay(calcMethod);?
calc.setCalcMethod(calcMethod);
try?{
calc.calc();
fail("Exception did not occur");
}?catch?(PositionException e) {
}
calc.setPosition(Position.BOSS);
assertEquals(70000.0, calc.calc());
assertEquals(70000.0, calc.calc());
calc.setPosition(Position.PROGRAMMER);
assertEquals(50000.0, calc.calc());
calc.setPosition(Position.SURFER);
EasyMock.verify(calcMethod);
}
@Test(expected = CalcMethodException.class)
public?void?testNoCalc() {
calc.setPosition(Position.SURFER);
calc.calc();
}
@Test(expected = PositionException.class)
public?void?testNoPosition() {
EasyMock.expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0);
EasyMock.replay(calcMethod);
calc.setCalcMethod(calcMethod);
calc.calc();
}
@Test(expected = PositionException.class)
public?void?testCalc2() {
// Setting up the expected value of the method call calc
EasyMock.expect(calcMethod.calc(Position.SURFER)).andThrow(new?PositionException("Don't know?this?guy")).times(1);?
// Setup is finished need to activate the mock
EasyMock.replay(calcMethod);
calc.setPosition(Position.SURFER);
calc.setCalcMethod(calcMethod);
calc.calc();
}
?
?
?
?
?
?
?
??expect方法告知EasyMock希望得到一個(gè)特定的方法,使用一些特定的參數(shù),addReturn為某一個(gè)方法定義返回值。times方法定義了模擬對象將被調(diào)用幾次。?reply方法需要在讓模擬對象可用之前被調(diào)用。執(zhí)行完測試之后,你可以調(diào)用verify方法來檢查模擬對象是不是跟預(yù)期的一樣被調(diào)用了。
?
1、mock次數(shù)的設(shè)置
times(int count): 要以范圍的方式定義調(diào)用次數(shù),能夠使用其他方法代替times(int count): times(int min, int max) to?expect between?min?and?max?calls, 用上下限指定方法調(diào)用次數(shù)。 atLeastOnce() to?expect at least one call, and 指定該方法至少被調(diào)用一次。 anyTimes() to?expected an unrestricted number of calls. 不限制對該方法的調(diào)用。
?
2、接口、抽象類、類的mock
org.easymock.classextension.EasyMock 被用來mock抽象類(abstract)和具體類?
org.easymock.EasyMock被用來mock接口(interface)?
3、創(chuàng)建多個(gè) Mock 對象,EasyMock 提供了另外一種生成和管理 Mock 對象的機(jī)制
| IMocksControl control = EasyMock.createControl(); java.sql.Connection mockConnection = control.createMock(Connection.class); java.sql.Statement mockStatement = control.createMock(Statement.class); java.sql.ResultSet mockResultSet = control.createMock(ResultSet.class); |
?4、多個(gè)接口進(jìn)行mock, 且之間存在相互關(guān)系, 例子如下:
?
?
?本文轉(zhuǎn)自 tianya23 51CTO博客,原文鏈接:http://blog.51cto.com/tianya23/268397,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的EasyMock基本使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 格式化磁盘
- 下一篇: rocketmq消费负载均衡--push