您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 >
EasyMock使用方法與原理剖析
作者:網(wǎng)絡轉(zhuǎn)載 發(fā)布時間:[ 2013/2/21 13:32:40 ] 推薦標簽:

在重新初始化之后,Mock 對象的狀態(tài)將被置為 Record 狀態(tài)。

3.在 EasyMock 中使用參數(shù)匹配器

EasyMock 預定義的參數(shù)匹配器

在使用 Mock 對象進行實際的測試過程中,EasyMock 會根據(jù)方法名和參數(shù)來匹配一個預期方法的調(diào)用。EasyMock 對參數(shù)的匹配默認使用 equals() 方法進行比較。這可能會引起一些問題。例如在上一章節(jié)中創(chuàng)建的mockStatement對象:

mockStatement.executeQuery("SELECT * FROM sales_order_table");
expectLastCall().andStubReturn(mockResultSet);


在實際的調(diào)用中,我們可能會遇到 SQL 語句中某些關(guān)鍵字大小寫的問題,例如將 SELECT 寫成 Select,這時在實際的測試中,EasyMock 所采用的默認匹配器將認為這兩個參數(shù)不匹配,從而造成 Mock 對象的預期方法不被調(diào)用。EasyMock 提供了靈活的參數(shù)匹配方式來解決這個問題。如果您對 mockStatement 具體執(zhí)行的語句并不關(guān)注,并希望所有輸入的字符串都能匹配這一方法調(diào)用,您可以用 org.easymock.EasyMock 類所提供的 anyObject 方法來代替參數(shù)中的 SQL 語句:

mockStatement.executeQuery( anyObject() );
expectLastCall().andStubReturn(mockResultSet);


anyObject 方法表示任意輸入值都與預期值相匹配。除了 anyObject 以外,EasyMock還提供了多個預先定義的參數(shù)匹配器,其中比較常用的一些有:

    aryEq(X value):通過Arrays.equals()進行匹配,適用于數(shù)組對象;
    isNull():當輸入值為Null時匹配;
    notNull():當輸入值不為Null時匹配;
    same(X value):當輸入值和預期值是同一個對象時匹配;
    lt(X value), leq(X value), geq(X value), gt(X value):當輸入值小于、小等于、大等于、大于預期值時匹配,適用于數(shù)值類型;
    startsWith(String prefix), contains(String substring), endsWith(String suffix):當輸入值以預期值開頭、包含預期值、以預期值結(jié)尾時匹配,適用于String類型;
    matches(String regex):當輸入值與正則表達式匹配時匹配,適用于String類型。

自定義參數(shù)匹配器

預定義的參數(shù)匹配器可能無法滿足一些復雜的情況,這時你需要定義自己的參數(shù)匹配器。在上一節(jié)中,我們希望能有一個匹配器對 SQL 中關(guān)鍵字的大小寫不敏感,使用 anyObject 其實并不是一個好的選擇。對此,我們可以定義自己的參數(shù)匹配器 SQLEquals。

要定義新的參數(shù)匹配器,需要實現(xiàn) org.easymock.IArgumentMatcher 接口。其中,matches(Object actual) 方法應當實現(xiàn)輸入值和預期值的匹配邏輯,而在 appendTo(StringBuffer buffer) 方法中,你可以添加當匹配失敗時需要顯示的信息。以下是 SQLEquals 實現(xiàn)的部分代碼(完整的代碼可以在 src.zip 中找到):

清單5:自定義參數(shù)匹配器SQLEquals

               
public class SQLEquals implements IArgumentMatcher {
  private String expectedSQL = null;
  public SQLEquals(String expectedSQL) {
    this.expectedSQL = expectedSQL;
  }
  ......
  public boolean matches(Object actualSQL) {
    if (actualSQL == null && expectedSQL == null)
      return true;
    else if (actualSQL instanceof String)
      return expectedSQL.equalsIgnoreCase((String) actualSQL);
    else
      return false;
  }
}


在實現(xiàn)了 IArgumentMatcher 接口之后,我們需要寫一個靜態(tài)方法將它包裝一下。這個靜態(tài)方法的實現(xiàn)需要將 SQLEquals 的一個對象通過 reportMatcher 方法報告給EasyMock:

清單6:自定義參數(shù)匹配器 SQLEquals 靜態(tài)方法

               
public static String sqlEquals(String in) {
  reportMatcher(new SQLEquals(in));
  return in;
}


這樣,我們自定義的 sqlEquals 匹配器可以使用了。我們可以將上例中的 executeQuery 方法設定修改如下:

mockStatement.executeQuery(sqlEquals("SELECT * FROM sales_order_table"));
expectLastCall().andStubReturn(mockResultSet);

 

在使用 executeQuery("select * from sales_order_table") 進行方法調(diào)用時,該預期行為將被匹配。

4.特殊的 Mock 對象類型

到目前為止,我們所創(chuàng)建的 Mock 對象都屬于 EasyMock 默認的 Mock 對象類型,它對預期方法的調(diào)用次序不敏感,對非預期的方法調(diào)用拋出 AssertionError。除了這種默認的 Mock 類型以外,EasyMock 還提供了一些特殊的 Mock 類型用于支持不同的需求。

Strick Mock 對象

如果 Mock 對象是通過 EasyMock.createMock() 或是 IMocksControl.createMock() 所創(chuàng)建的,那么在進行 verify 驗證時,方法的調(diào)用順序是不進行檢查的。如果要創(chuàng)建方法調(diào)用的先后次序敏感的 Mock 對象(Strick Mock),應該使用 EasyMock.createStrickMock() 來創(chuàng)建,例如:

ResultSet strickMockResultSet = createStrickMock(ResultSet.class);


類似于 createMock,我們同樣可以用 IMocksControl 實例來創(chuàng)建一個 Strick Mock 對象:

IMocksControl control = EasyMock.createStrictControl();
ResultSet strickMockResultSet = control.createMock(ResultSet.class);


Nice Mock 對象

使用 createMock() 創(chuàng)建的 Mock 對象對非預期的方法調(diào)用默認的行為是拋出 AssertionError,如果需要一個默認返回0,null 或 false 等"無效值"的 "Nice Mock" 對象,可以通過 EasyMock 類提供的 createNiceMock() 方法創(chuàng)建。類似的,你也可以用

5.EasyMock 的工作原理

EasyMock 是如何為一個特定的接口動態(tài)創(chuàng)建 Mock 對象,并記錄 Mock 對象預期行為的呢?其實,EasyMock 后臺處理的主要原理是利用 java.lang.reflect.Proxy 為指定的接口創(chuàng)建一個動態(tài)代理,這個動態(tài)代理,是我們在編碼中用到的 Mock 對象。EasyMock 還為這個動態(tài)代理提供了一個 InvocationHandler 接口的實現(xiàn),這個實現(xiàn)類的主要功能是將動態(tài)代理的預期行為記錄在某個映射表中和在實際調(diào)用時從這個映射表中取出預期輸出。下圖是 EasyMock 中主要的功能類:

圖4:EasyMock主要功能類

和開發(fā)人員聯(lián)系緊密的是 EasyMock 類,這個類提供了 createMock、replay、verify 等方法以及所有預定義的參數(shù)匹配器。

上一頁12345下一頁
軟件測試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd