日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

EasyMock 使用方法与原理剖析

發布時間:2025/3/21 编程问答 72 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EasyMock 使用方法与原理剖析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Mock 方法是單元測試中常見的一種技術,它的主要作用是模擬一些在應用中不容易構造或者比較復雜的對象,從而把測試與測試邊界以外的對象隔離開。

編寫自定義的 Mock 對象需要額外的編碼工作,同時也可能引入錯誤。EasyMock 提供了根據指定接口動態構建 Mock 對象的方法,避免了手工編寫 Mock 對象。本文將向您展示如何使用 EasyMock 進行單元測試,并對 EasyMock 的原理進行分析。

1.Mock 對象與 EasyMock 簡介

單元測試與 Mock 方法

單元測試是對應用中的某一個模塊的功能進行驗證。在單元測試中,我們常遇到的問題是應用中其它的協同模塊尚未開發完成,或者被測試模塊需要和一些不容易構造、比較復雜的對象進行交互。另外,由于不能肯定其它模塊的正確性,我們也無法確定測試中發現的問題是由哪個模塊引起的。

Mock 對象能夠模擬其它協同模塊的行為,被測試模塊通過與 Mock 對象協作,可以獲得一個孤立的測試環境。此外,使用 Mock 對象還可以模擬在應用中不容易構造(如 HttpServletRequest 必須在 Servlet 容器中才能構造出來)和比較復雜的對象(如 JDBC 中的 ResultSet 對象),從而使測試順利進行。

EasyMock 簡介

手動的構造 Mock 對象會給開發人員帶來額外的編碼量,而且這些為創建 Mock 對象而編寫的代碼很有可能引入錯誤。目前,有許多開源項目對動態構建 Mock 對象提供了支持,這些項目能夠根據現有的接口或類動態生成,這樣不僅能避免額外的編碼工作,同時也降低了引入錯誤的可能。

EasyMock 是一套用于通過簡單的方法對于給定的接口生成 Mock 對象的類庫。它提供對接口的模擬,能夠通過錄制、回放、檢查三步來完成大體的測試過程,可以驗證方法的調用種類、次數、順序,可以令 Mock 對象返回指定的值或拋出指定異常。通過 EasyMock,我們可以方便的構造 Mock 對象從而使單元測試順利進行。

安裝 EasyMock

EasyMock 是采用 MIT license 的一個開源項目,您可以在 Sourceforge 上下載到相關的 zip 文件。目前您可以下載的 EasyMock 最新版本是2.3,它需要運行在 Java 5.0 平臺上。如果您的應用運行在 Java 1.3 或 1.4 平臺上,您可以選擇 EasyMock1.2。在解壓縮 zip 包后,您可以找到 easymock.jar 這個文件。如果您使用 Eclipse 作為 IDE,把 easymock.jar 添加到項目的 Libraries 里就可以使用了(如下圖所示)。此外,由于我們的測試用例運行在 JUnit 環境中,因此您還需要 JUnit.jar(版本3.8.1以上)。

圖1:Eclipse 項目中的 Libraries

2.使用 EasyMock 進行單元測試

通過 EasyMock,我們可以為指定的接口動態的創建 Mock 對象,并利用 Mock 對象來模擬協同模塊或是領域對象,從而使單元測試順利進行。這個過程大致可以劃分為以下幾個步驟:

  • 使用 EasyMock 生成 Mock 對象;
  • 設定 Mock 對象的預期行為和輸出;
  • 將 Mock 對象切換到 Replay 狀態;
  • 調用 Mock 對象方法進行單元測試;
  • 對 Mock 對象的行為進行驗證。

接下來,我們將對以上的幾個步驟逐一進行說明。除了以上的基本步驟外,EasyMock 還對特殊的 Mock 對象類型、特定的參數匹配方式等功能提供了支持,我們將在之后的章節中進行說明。

使用 EasyMock 生成 Mock 對象

根據指定的接口或類,EasyMock 能夠動態的創建 Mock 對象(EasyMock 默認只支持為接口生成 Mock 對象,如果需要為類生成 Mock 對象,在 EasyMock 的主頁上有擴展包可以實現此功能),我們以?ResultSet?接口為例說明EasyMock的功能。java.sql.ResultSet?是每一個 Java 開發人員都非常熟悉的接口:

清單1:ResultSet 接口
public interface java.sql.ResultSet { ...... public abstract java.lang.String getString(int arg0) throws java.sql.SQLException; public abstract double getDouble(int arg0) throws java.sql.SQLException; ...... }

通常,構建一個真實的?RecordSet?對象需要經過一個復雜的過程:在開發過程中,開發人員通常會編寫一個?DBUtility?類來獲取數據庫連接?Connection,并利用?Connection?創建一個?Statement。執行一個?Statement?可以獲取到一個或多個?ResultSet?對象。這樣的構造過程復雜并且依賴于數據庫的正確運行。數據庫或是數據庫交互模塊出現問題,都會影響單元測試的結果。

我們可以使用 EasyMock 動態構建?ResultSet?接口的 Mock 對象來解決這個問題。一些簡單的測試用例只需要一個 Mock 對象,這時,我們可以用以下的方法來創建 Mock 對象:

ResultSet mockResultSet = createMock(ResultSet.class);

其中?createMock?是?org.easymock.EasyMock?類所提供的靜態方法,你可以通過 static import 將其引入(注:static import 是 java 5.0 所提供的新特性)。

如果需要在相對復雜的測試用例中使用多個 Mock 對象,EasyMock 提供了另外一種生成和管理 Mock 對象的機制:

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);

EasyMock?類的?createControl?方法能創建一個接口?IMocksControl?的對象,該對象能創建并管理多個 Mock 對象。如果需要在測試中使用多個 Mock 對象,我們推薦您使用這一機制,因為它在多個 Mock 對象的管理上提供了相對便捷的方法。

如果您要模擬的是一個具體類而非接口,那么您需要下載擴展包 EasyMock Class Extension 2.2.2。在對具體類進行模擬時,您只要用?org.easymock.classextension.EasyMock?類中的靜態方法代替?org.easymock.EasyMock?類中的靜態方法即可。

設定 Mock 對象的預期行為和輸出

在一個完整的測試過程中,一個 Mock 對象將會經歷兩個狀態:Record 狀態和 Replay 狀態。Mock 對象一經創建,它的狀態就被置為 Record。在 Record 狀態,用戶可以設定 Mock 對象的預期行為和輸出,這些對象行為被錄制下來,保存在 Mock 對象中。

添加 Mock 對象行為的過程通常可以分為以下3步:

  • 對 Mock 對象的特定方法作出調用;
  • 通過?org.easymock.EasyMock?提供的靜態方法?expectLastCall?獲取上一次方法調用所對應的 IExpectationSetters 實例;
  • 通過?IExpectationSetters?實例設定 Mock 對象的預期輸出。

設定預期返回值

Mock 對象的行為可以簡單的理解為 Mock 對象方法的調用和方法調用所產生的輸出。在 EasyMock 2.3 中,對 Mock 對象行為的添加和設置是通過接口?IExpectationSetters?來實現的。Mock 對象方法的調用可能產生兩種類型的輸出:(1)產生返回值;(2)拋出異常。接口?IExpectationSetters?提供了多種設定預期輸出的方法,其中和設定返回值相對應的是 andReturn 方法:

IExpectationSetters<T> andReturn(T value);

我們仍然用?ResultSet?接口的 Mock 對象為例,如果希望方法?mockResult.getString(1)?的返回值為 "My return value",那么你可以使用以下的語句:

mockResultSet.getString(1); expectLastCall().andReturn("My return value");

以上的語句表示?mockResultSet?的?getString?方法被調用一次,這次調用的返回值是 "My return value"。有時,我們希望某個方法的調用總是返回一個相同的值,為了避免每次調用都為 Mock 對象的行為進行一次設定,我們可以用設置默認返回值的方法:

void andStubReturn(Object value);

假設我們創建了?Statement?和?ResultSet?接口的 Mock 對象 mockStatement 和 mockResultSet,在測試過程中,我們希望 mockStatement 對象的?executeQuery?方法總是返回 mockResultSet,我們可以使用如下的語句

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

EasyMock 在對參數值進行匹配時,默認采用?Object.equals()?方法。因此,如果我們以?"select * from sales_order_table"?作為參數,預期方法將不會被調用。如果您希望上例中的 SQL 語句能不區分大小寫,可以用特殊的參數匹配器來解決這個問題,我們將在 "在 EasyMock 中使用參數匹配器" 一章對此進行說明。

設定預期異常拋出

對象行為的預期輸出除了可能是返回值外,還有可能是拋出異常。IExpectationSetters?提供了設定預期拋出異常的方法:

IExpectationSetters<T> andThrow(Throwable throwable);

和設定默認返回值類似,IExpectationSetters?接口也提供了設定拋出默認異常的函數:

void andStubThrow(Throwable throwable);

設定預期方法調用次數

通過以上的函數,您可以對 Mock 對象特定行為的預期輸出進行設定。除了對預期輸出進行設定,IExpectationSetters?接口還允許用戶對方法的調用次數作出限制。在?IExpectationSetters?所提供的這一類方法中,常用的一種是?times?方法:

IExpectationSetters<T>times(int count);

該方法可以 Mock 對象方法的調用次數進行確切的設定。假設我們希望 mockResultSet 的?getString?方法在測試過程中被調用3次,期間的返回值都是 "My return value",我們可以用如下語句:

mockResultSet.getString(1); expectLastCall().andReturn("My return value").times(3);


注意到?andReturn?和?andThrow?方法的返回值依然是一個?IExpectationSetters?實例,因此我們可以在此基礎上繼續調用?times?方法。

除了設定確定的調用次數,IExpectationSetters?還提供了另外幾種設定非準確調用次數的方法:
times(int minTimes, int maxTimes):該方法最少被調用 minTimes 次,最多被調用 maxTimes 次。
atLeastOnce():該方法至少被調用一次。
anyTimes():該方法可以被調用任意次。

某些方法的返回值類型是 void,對于這一類方法,我們無需設定返回值,只要設置調用次數就可以了。以?ResultSet?接口的?close?方法為例,假設在測試過程中,該方法被調用3至5次:

mockResultSet.close(); expectLastCall().times(3, 5);

為了簡化書寫,EasyMock 還提供了另一種設定 Mock 對象行為的語句模式。對于上例,您還可以將它寫成:

expect(mockResult.close()).times(3, 5);


這個語句和上例中的語句功能是完全相同的。

將 Mock 對象切換到 Replay 狀態

在生成 Mock 對象和設定 Mock 對象行為兩個階段,Mock 對象的狀態都是 Record 。在這個階段,Mock 對象會記錄用戶對預期行為和輸出的設定。

在使用 Mock 對象進行實際的測試前,我們需要將 Mock 對象的狀態切換為 Replay。在 Replay 狀態,Mock 對象能夠根據設定對特定的方法調用作出預期的響應。將 Mock 對象切換成 Replay 狀態有兩種方式,您需要根據 Mock 對象的生成方式進行選擇。如果 Mock 對象是通過?org.easymock.EasyMock?類提供的靜態方法 createMock 生成的(第1節中介紹的第一種 Mock 對象生成方法),那么?EasyMock?類提供了相應的 replay 方法用于將 Mock 對象切換為 Replay 狀態:

replay(mockResultSet);

如果 Mock 對象是通過?IMocksControl?接口提供的?createMock?方法生成的(第1節中介紹的第二種Mock對象生成方法),那么您依舊可以通過?IMocksControl?接口對它所創建的所有 Mock 對象進行切換:

control.replay();

以上的語句能將在第1節中生成的 mockConnection、mockStatement 和 mockResultSet 等3個 Mock 對象都切換成 Replay 狀態。

調用 Mock 對象方法進行單元測試

為了更好的說明 EasyMock 的功能,我們引入 src.zip 中的示例來解釋 Mock 對象在實際測試階段的作用。其中所有的示例代碼都可以在 src.zip 中找到。如果您使用的 IDE 是 Eclipse,在導入 src.zip 之后您可以看到 Workspace 中增加的 project(如下圖所示)。

圖2:導入 src.zip 后的 Workspace

下面是示例代碼中的一個接口?SalesOrder,它的實現類?SalesOrderImpl?的主要功能是從數據庫中讀取一個 Sales Order 的 Region 和 Total Price,并根據讀取的數據計算該 Sales Order 的 Price Level(完整的實現代碼都可以在 src.zip 中找到):

清單2:SalesOrder 接口
public interface SalesOrder {……public void loadDataFromDB(ResultSet resultSet) throws SQLException; public String getPriceLevel(); }

其實現類?SalesOrderImpl?中對?loadDataFromDB?的實現如下:

清單3:SalesOrderImpl 實現
public class SalesOrderImpl implements SalesOrder {......public void loadDataFromDB(ResultSet resultSet) throws SQLException{orderNumber = resultSet.getString(1);region = resultSet.getString(2);totalPrice = resultSet.getDouble(3);}...... }

方法?loadDataFromDB?讀取了?ResultSet?對象包含的數據。當我們將之前定義的 Mock 對象調整為 Replay 狀態,并將該對象作為參數傳入,那么 Mock 對象的方法將會返回預先定義的預期返回值。完整的 TestCase 如下:

清單4:完整的TestCase
public class SalesOrderTestCase extends TestCase {public void testSalesOrder() {IMocksControl control = EasyMock.createControl();......ResultSet mockResultSet = control.createMock(ResultSet.class);try {......mockResultSet.next();expectLastCall().andReturn(true).times(3);expectLastCall().andReturn(false).times(1);mockResultSet.getString(1);expectLastCall().andReturn("DEMO_ORDER_001").times(1);expectLastCall().andReturn("DEMO_ORDER_002").times(1);expectLastCall().andReturn("DEMO_ORDER_003").times(1);mockResultSet.getString(2);expectLastCall().andReturn("Asia Pacific").times(1);expectLastCall().andReturn("Europe").times(1);expectLastCall().andReturn("America").times(1);mockResultSet.getDouble(3);expectLastCall().andReturn(350.0).times(1);expectLastCall().andReturn(1350.0).times(1);expectLastCall().andReturn(5350.0).times(1);control.replay();......int i = 0;String[] priceLevels = { "Level_A", "Level_C", "Level_E" };while (mockResultSet.next()) {SalesOrder order = new SalesOrderImpl();order.loadDataFromDB(mockResultSet);assertEquals(order.getPriceLevel(), priceLevels[i]);i++;}control.verify();} catch (Exception e) {e.printStackTrace();}} }

在這個示例中,我們首先創建了?ResultSet?的 Mock 對象 moResultSet,并記錄該 Mock 對象的預期行為。之后我們調用了?control.replay(),將 Mock 對象的狀態置為 Replay 狀態。 在實際的測試階段,Sales Order 對象的?loadDataFromDB?方法調用了 mockResultSet 對象的?getString?和?getDouble?方法讀取 mockResultSet 中的數據。Sales Order 對象根據讀取的數據計算出 Price Level,并和預期輸出進行比較。

對 Mock 對象的行為進行驗證

在利用 Mock 對象進行實際的測試過程之后,我們還有一件事情沒有做:對 Mock 對象的方法調用的次數進行驗證。

為了驗證指定的方法調用真的完成了,我們需要調用?verify?方法進行驗證。和?replay?方法類似,您需要根據 Mock 對象的生成方式來選用不同的驗證方式。如果 Mock 對象是由?org.easymock.EasyMock?類提供的?createMock?靜態方法生成的,那么我們同樣采用?EasyMock?類的靜態方法?verify?進行驗證:

verify(mockResultSet);

如果Mock對象是有?IMocksControl?接口所提供的?createMock?方法生成的,那么采用該接口提供的?verify?方法,例如第1節中的?IMocksControl?實例 control:

control.verify();

將對 control 實例所生成的 Mock 對象 mockConnection、mockStatement 和 mockResultSet 等進行驗證。如果將上例中?expectLastCall().andReturn(false).times(1)?的預期次數修改為2,在 Eclipse 中將可以看到:

圖3:Mock對象驗證失敗

Mock 對象的重用

為了避免生成過多的 Mock 對象,EasyMock 允許對原有 Mock 對象進行重用。要對 Mock 對象重新初始化,我們可以采用 reset 方法。和 replay 和 verify 方法類似,EasyMock 提供了兩種 reset 方式:(1)如果 Mock 對象是由?org.easymock.EasyMock?類中的靜態方法?createMock生成的,那么該 Mock 對象的可以用?EasyMock?類的靜態方法?reset?重新初始化;(2)如果 Mock 方法是由?IMocksControl?實例的?createMock?方法生成的,那么該?IMocksControl?實例方法?reset?的調用將會把所有該實例創建的 Mock 對象重新初始化。

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

3.在 EasyMock 中使用參數匹配器

EasyMock 預定義的參數匹配器

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

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

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

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

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

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

自定義參數匹配器

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

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

清單5:自定義參數匹配器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);elsereturn false;} }

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

清單6:自定義參數匹配器 SQLEquals 靜態方法
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")?進行方法調用時,該預期行為將被匹配。

4.特殊的 Mock 對象類型

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

Strick Mock 對象

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

ResultSet strickMockResultSet = createStrickMock(ResultSet.class);

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

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

Nice Mock 對象

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

5.EasyMock 的工作原理

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

圖4:EasyMock主要功能類

和開發人員聯系最緊密的是?EasyMock?類,這個類提供了?createMock、replay、verify?等方法以及所有預定義的參數匹配器。

我們知道 Mock 對象有兩種創建方式:一種是通過?EasyMock?類提供的?createMock?方法創建,另一種是通過?EasyMock?類的?createControl?方法得到一個?IMocksControl?實例,再由這個?IMocksControl?實例創建 Mock 對象。其實,無論通過哪種方法獲得 Mock 對象,EasyMock 都會生成一個?IMocksControl?的實例,只不過第一種方式中的?IMocksControl?的實例對開發人員不可見而已。這個?IMocksControl?的實例,其實就是?MocksControl?類的一個對象。MocksControl?類提供了?andReturn、andThrow、times、createMock?等方法。

MocksControl?類中包含了兩個重要的成員變量,分別是接口?IMocksBehavior?和?IMocksControlState?的實例。其中,IMocksBehavior?的實現類?MocksBehavior?是 EasyMock 的核心類,它保存著一個?ExpectedInvocationAndResult?對象的一個列表,而?ExpectedInvocationAndResult?對象中包含著 Mock 對象方法調用和預期結果的映射。MocksBehavior?類提供了?addExpected和?addActual?方法用于添加預期行為和實際調用。

MocksControl?類中包含的另一個成員變量是?IMocksControlState?實例。IMocksControlState?擁有兩個不同的實現類:RecordState?和?ReplayState。顧名思義,RecordState?是 Mock 對象在 Record 狀態時的支持類,它提供了?invoke?方法在 Record 狀態下的實現。此外,它還提供了?andReturn、andThrow、times?等方法的實現。ReplayState?是 Mock 對象在 Replay 狀態下的支持類,它提供了?invoke?方法在 Replay 狀態下的實現。在 ReplayState 中,andReturn、andThrow、times?等方法的實現都是拋出IllegalStateException,因為在 Replay 階段,開發人員不應該再調用這些方法。

當我們調用?MocksControl?的?createMock?方法時,該方法首先會生成一個?JavaProxyFactory?類的對象。JavaProxyFactory?是接口?IProxyFactory?的實現類,它的主要功能就是通過?java.lang.reflect.Proxy?對指定的接口創建動態代理實例,也就是開發人員在外部看到的 Mock 對象。

在創建動態代理的同時,應當提供?InvocationHandler?的實現類。MockInvocationHandler?實現了這個接口,它的?invoke?方法主要的功能是根據 Mock 對象狀態的不同而分別調用?RecordState?的?invoke?實現或是?ReplayState?的?invoke?實現。

創建 Mock 對象

下圖是創建 Mock 對象的時序圖:

圖5:創建 Mock 對象時序圖

當?EasyMock?類的?createMock?方法被調用時,它首先創建一個?MocksControl?對象,并調用該對象的?createMock?方法創建一個?JavaProxyFactory?對象和一個?MockInvocationHandler?對象。JavaProxyFactory?對象將?MockInvocationHandler?對象作為參數,通過?java.lang.reflect.Proxy?類的?newProxyInstance?靜態方法創建一個動態代理。

記錄 Mock 對象預期行為

記錄 Mock 的預期行為可以分為兩個階段:預期方法的調用和預期輸出的設定。在外部程序中獲得的 Mock 對象,其實就是由?JavaProxyFactory?創建的指定接口的動態代理,所有外部程序對接口方法的調用,都會指向?InvocationHandler?實現類的?invoke?方法。在 EasyMock 中,這個實現類是?MockInvocationHandler。下圖是調用預期方法的時序圖:

圖6:調用預期方法時序圖

當?MockInvocationHandler?的?invoke?方法被調用時,它首先通過?reportLastControl?靜態方法將 Mock 對象對應的?MocksControl對象報告給?LastControl?類,LastControl?類將該對象保存在一個 ThreadLocal 變量中。接著,MockInvocationHandler?將創建一個 Invocation 對象,這個對象將保存預期調用的 Mock 對象、方法和預期參數。

在記錄 Mock 對象預期行為時,Mock 對象的狀態是 Record 狀態,因此?RecordState?對象的?invoke?方法將被調用。這個方法首先調用?LastControl?的?pullMatchers?方法獲取參數匹配器。如果您還記得自定義參數匹配器的過程,應該能想起參數匹配器被調用時會將實現類的實例報告給 EasyMock,而這個實例最終保存在?LastControl?中。如果沒有指定參數匹配器,默認的匹配器將會返回給?RecordState。

根據?Invocation?對象和參數匹配器,RecordState?將創建一個?ExpectedInvocation?對象并保存下來。

在對預期方法進行調用之后,我們可以對該方法的預期輸出進行設定。我們以

expectLastCall().andReturn(X value).times(int times)


為例說明。如果?times?方法未被顯式的調用,EasyMock 會默認作為?times(1)?處理。下圖是設定預期輸出的時序圖:

圖7:設定預期輸出時序圖

在預期方法被調用時,Mock 對象對應的?MocksControl?對象引用已經記錄在?LastControl?中,expectLastCall?方法通過調用?LastControl?的?lastControl?方法可以獲得這個引用。MocksControl?對象的?andReturn?方法在 Mock 對象 Record 狀態下會調用?RecordState?的?andReturn?方法,將設定的預期輸出以?Result?對象的形式記錄下來,保存在?RecordState?的 lastResult 變量中。

當?MocksControl?的?times?方法被調用時,它會檢查?RecordState?的 lastResult 變量是否為空。如果不為空,則將 lastResult 和預期方法被調用時創建的?ExpectedInvocation?對象一起,作為參數傳遞給?MocksBehavior?的?addExpected?方法。MocksBehavior?的?addExpected?方法將這些信息保存在數據列表中。

在 Replay 狀態下調用 Mock 對象方法

EasyMock?類的?replay?方法可以將 Mock 對象切換到 Replay 狀態。在 Replay 狀態下,Mock 對象將根據之前的設定返回預期輸出。下圖是 Replay 狀態下 Mock 對象方法調用的時序圖:

圖8:調用 Mock 對象方法時序圖

在 Replay 狀態下,MockInvocationHandler?會調用?ReplayState?的?invoke?方法。該方法會把 Mock 對象通過?MocksBehavior?的?addActual?方法添加到實際調用列表中,該列表在?verify?方法被調用時將被用到。同時,addActual?方法會根據實際方法調用與預期方法調用進行匹配,返回對應的?Result?對象。調用?Result?對象的?answer?方法就可以獲取該方法調用的輸出。

6.使用 EasyMock 進行單元測試小結

如果您需要在單元測試中構建 Mock 對象來模擬協同模塊或一些復雜對象,EasyMock 是一個可以選用的優秀框架。EasyMock 提供了簡便的方法創建 Mock 對象:通過定義 Mock 對象的預期行為和輸出,你可以設定該 Mock 對象在實際測試中被調用方法的返回值、異常拋出和被調用次數。通過創建一個可以替代現有對象的 Mock 對象,EasyMock 使得開發人員在測試時無需編寫自定義的 Mock 對象,從而避免了額外的編碼工作和因此引入錯誤的機會。

下載

描述 名字 大小 本文用到的示例代碼
src.zip 176KB

參考資料

學習

  • 如果您想要獲得 EasyMock 完整的文檔和 API,您可以訪問 EasyMock 的主頁:http://www.easymock.org/。
  • 您可以在 JUnit 的主頁上找到完整的文檔和相關下載:http://www.junit.org/index.htm。
  • 通過 Developer Works 上的文章,您可以和其它的框架做比較:利用 Eclipse 進行單元測試。

獲得產品和技術

  • 在Source Forge上,你可以下載到最新的 EasyMock 相關代碼:http://sourceforge.net/project/showfiles.php?group_id=82958。
  • Eclipse 的相關下載可以在?http://www.eclipse.org/?上找到。
  • from:?http://www.ibm.com/developerworks/cn/opensource/os-cn-easymock/

總結

以上是生活随笔為你收集整理的EasyMock 使用方法与原理剖析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

久精品视频免费观看2 | 日本韩国欧美在线观看 | 精品国产免费av | 综合色在线观看 | 亚洲激情五月 | 欧美日韩在线观看不卡 | 免费福利在线 | 免费av成人在线 | 亚洲小视频在线观看 | 日韩69视频| 国产精品久久久久久久免费大片 | 国产大尺度视频 | 亚洲在线观看av | 97免费在线观看视频 | 玖玖综合网 | 五月天婷婷在线播放 | 亚洲自拍自偷 | 中文字幕精| 在线观看中文字幕一区二区 | 色中色亚洲 | 99久久精品久久久久久清纯 | 国产精品黄色影片导航在线观看 | 97电影网手机版 | 国产呻吟在线 | 五月婷婷黄色 | 岛国av在线不卡 | 国产一级精品绿帽视频 | 欧美午夜理伦三级在线观看 | 国产亚洲精品日韩在线tv黄 | 欧美日韩国产精品一区二区三区 | 国产精品一区久久久久 | 中文字幕丝袜制服 | av黄免费看| 97狠狠干 | 玖草影院 | 4438全国亚洲精品观看视频 | 中文字幕在线播放日韩 | 天堂成人在线 | 日韩欧美一区二区在线播放 | 久草视频在线资源 | 成人av一二三区 | 日韩激情在线 | 成人久久久久久久久久 | 免费观看的黄色片 | 中文字幕欧美激情 | 免费在线观看污 | 狠狠操狠狠干天天操 | 91av手机在线 | 婷婷av网 | 亚洲国产影院av久久久久 | 中文字幕在线观看三区 | 日韩中文字幕第一页 | 国产爽妇网 | 91最新在线 | 久久经典国产 | 亚洲国产午夜精品 | 四虎国产精品永久在线国在线 | 成人在线播放免费观看 | 久久综合九色综合97婷婷女人 | 四虎影视精品永久在线观看 | 一二三精品视频 | 中文av在线免费观看 | 在线成人性视频 | 国产一区二区三区网站 | 人人射人人爱 | 黄色精品免费 | 国产97视频 | 午夜影院先 | 91豆花在线 | 免费看的黄色小视频 | 国产精品久久久久久久久久久久久久 | 久久久久中文 | 激情中文在线 | 91九色蝌蚪视频 | 亚洲精品乱码久久久久久高潮 | 天天想夜夜操 | 国产亚洲精品久久19p | 欧美性生活免费看 | 在线av资源 | 色婷婷色| 成年人免费在线观看网站 | 天天激情在线 | 亚洲三级国产 | 亚洲aⅴ一区二区三区 | 国产精品欧美久久久久无广告 | 久草在线免费色站 | 国产成人高清av | 婷婷丁香社区 | 在线视频观看成人 | 青青射 | 成人免费看黄 | 最近日本mv字幕免费观看 | 玖玖爱免费视频 | 久精品视频在线观看 | 国产福利在线免费观看 | 久久久91精品国产一区二区三区 | 天天搞天天| 狠狠躁日日躁夜夜躁av | 国产精品久久久久高潮 | 欧美-第1页-屁屁影院 | 精品在线小视频 | 国精产品永久999 | 亚洲精品中文字幕在线观看 | 三级黄免费看 | 久久精品国亚洲 | 国产在线观看一区 | 国产一区二区免费在线观看 | 久久综合狠狠综合 | 97超碰在线播放 | 91大神精品视频在线观看 | 色婷婷综合久久久久 | 狠狠躁夜夜躁人人爽超碰91 | 操碰av| 国产不卡免费 | 久久天天综合网 | av超碰免费在线 | 精品久久久久久一区二区里番 | 国产夫妻av在线 | 久草在线视频免赞 | 中文字幕人成不卡一区 | 久久9精品 | 久久超碰在线 | 樱空桃av| 在线观看你懂的网址 | 激情小说网站亚洲综合网 | 亚洲综合成人av | 在线电影a | 日韩一级成人av | 在线视频福利 | 97在线看| 日本一区二区免费在线观看 | 免费观看国产成人 | 成人av片在线观看 | 国内精品久久久久久久久 | 日韩av播放在线 | 日韩免费网站 | 99视频在线精品免费观看2 | 91精品办公室少妇高潮对白 | 国产亚洲精品久久久久久 | 日韩精品视频在线观看免费 | 日本在线观看一区二区 | 97在线超碰 | 国内久久久| 一本色道久久综合亚洲二区三区 | 久久另类视频 | 国产69精品久久99的直播节目 | 亚洲午夜在线视频 | 亚洲欧洲精品视频 | 久久午夜电影 | 色婷婷久久一区二区 | 九九久 | 91看片看淫黄大片 | 久久精品视频一 | 欧美色综合久久 | 亚洲成av人片一区二区梦乃 | 国产九色在线播放九色 | 一本一道久久a久久综合蜜桃 | 日韩美视频 | 国产91av视频在线观看 | 高清免费在线视频 | 超碰成人免费电影 | 久久久在线视频 | 亚洲在线黄色 | 亚洲精品在线网站 | 国产精品亚州 | 免费看片网址 | 久久久www成人免费毛片 | 在线精品在线 | 国产精品久久久久久久久久久免费看 | 亚洲国产精品免费 | 国产麻豆精品传媒av国产下载 | 国产91探花| 精品黄色在线观看 | 日韩在线观看你懂得 | 欧美a级片网站 | 国产 中文 日韩 欧美 | 久久精品久久99 | 最近2019好看的中文字幕免费 | 久久久久看片 | 91污污视频在线观看 | 欧美日韩综合在线 | 欧美在线视频一区二区三区 | 激情五月婷婷丁香 | 久久久免费看片 | 狠狠狠色丁香婷婷综合久久88 | 狠狠色噜噜狠狠狠狠2022 | 精品亚洲免费 | 91麻豆精品国产91久久久更新时间 | 色五婷婷 | 日韩在线视 | 亚洲做受高潮欧美裸体 | 国产一级大片免费看 | 国产免费又爽又刺激在线观看 | 久久精品电影院 | 亚洲第一色 | 视频福利在线 | 少妇bbb好爽 | 日本三级久久久 | 亚洲码国产日韩欧美高潮在线播放 | 最近中文字幕国语免费高清6 | 96av在线| 久久国产亚洲精品 | 在线观看国产区 | 国产破处在线视频 | 操老逼免费视频 | 久久久久久久国产精品影院 | 国产一区二区在线免费播放 | 午夜国产一区二区三区四区 | 九色视频网站 | 色多多污污 | 视频 天天草 | 久久成人一区 | 国产又粗又猛又黄又爽的视频 | 国产在线一线 | 日韩在线资源 | 亚洲91网站| 免费福利影院 | 国产爽视频 | 精品亚洲男同gayvideo网站 | 黄色天堂在线观看 | 亚洲成年人在线播放 | 久久成人欧美 | 丁香六月婷婷开心 | 一区二区三区电影在线播 | 日韩在线观看你懂得 | 日韩精品在线一区 | 国产拍揄自揄精品视频麻豆 | 丰满少妇一级 | 久久精品中文字幕一区二区三区 | 日韩欧美一区二区三区在线 | 日韩欧美在线高清 | 永久精品视频 | 欧美成人精品在线 | 91精品久久久久久粉嫩 | 一区二区三区四区免费视频 | 97国产| 少妇高潮冒白浆 | 综合久久久久久 | 欧美在线91 | 国产精品一区二区三区在线看 | 国产色婷婷精品综合在线手机播放 | 精品国产一区二区三区久久久 | 99热这里只有精品在线观看 | 91插插影库 | 亚洲成人一二三 | 国产最顶级的黄色片在线免费观看 | 欧美亚洲一级片 | 91cn国产在线| 日韩综合色 | 国产精品麻豆91 | 久久大视频 | 日韩成人邪恶影片 | 中文字幕一区二区三区在线观看 | 在线观看国产日韩 | 美女网站视频免费都是黄 | 97综合在线| 日韩在线电影一区 | 人人添人人澡人人澡人人人爽 | 99精品免费网 | 久久久久久久久久久国产精品 | 国产日女人 | 国产免费专区 | 国产一区二区中文字幕 | 美女黄久久 | 久久精品国产一区二区电影 | 亚洲一区日韩精品 | 亚洲一级黄色大片 | 日韩黄色一区 | 久久66热这里只有精品 | 黄a在线| 日韩久久视频 | 日本少妇高清做爰视频 | 亚洲一区二区观看 | 国产欧美精品一区二区三区 | 日韩欧美一区视频 | 99在线观看视频 | 国产精品视频最多的网站 | 久久久久国产精品www | 日日夜夜亚洲 | 欧美日韩高清在线 | 91| 在线免费黄色av | 亚洲精品久久久蜜桃直播 | 91久久人澡人人添人人爽欧美 | 国产精品精品 | 91在线视频网址 | 黄污视频网站大全 | 久久伊人色综合 | 亚洲成人一区 | 欧美日韩色婷婷 | 国产精品成人a免费观看 | 久久不卡国产精品一区二区 | 国产精品一区一区三区 | 91亚洲精品在线观看 | 色综合久久久 | 欧美做受xxx | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 日韩乱色精品一区二区 | 99免费精品| 日韩网站在线免费观看 | 九九热久久免费视频 | 人人舔人人爱 | 国产在线观看免费观看 | 天天天天干 | 欧美日韩国产区 | 免费成人看片 | 亚洲精品自拍 | 91综合久久一区二区 | 亚洲在线视频网站 | 人人添人人 | 97超碰站 | 国产999| 国产精彩在线视频 | 久久精品黄色 | 激情五月婷婷丁香 | 在线成人一区 | 色综合天天综合 | 亚洲免费精品视频 | 国产麻豆视频 | 日本激情动作片免费看 | 天天干,天天操 | 最新国产视频 | 国产精品免费不卡 | 日韩免费视频线观看 | 精品国产伦一区二区三区观看说明 | 在线观看精品 | 99精品一区二区 | 久久久天天操 | 最近中文字幕国语免费av | 狠狠色伊人亚洲综合成人 | 国产免费精彩视频 | 天天爱天天干天天爽 | 国产色秀视频 | 欧洲成人av | 天天射综合网视频 | 国产黄a三级三级 | 男女免费av | 欧美日韩网址 | 国产午夜三级一二三区 | 黄色免费高清视频 | 亚洲精品在线播放视频 | 黄色av电影免费观看 | 国产欧美精品一区二区三区四区 | 日本3级在线观看 | 亚洲欧美一区二区三区孕妇写真 | 亚洲最新在线视频 | 日韩网页| 日韩 精品 一区 国产 麻豆 | 色天天| 四虎最新入口 | 日韩精品一区二区在线观看视频 | 久久不射电影院 | 色视频网址 | 91丨九色丨首页 | 狠狠干狠狠久久 | 精品国产诱惑 | 日韩av高潮| 99精品国自产在线 | 中文字幕在线观看播放 | 亚洲第一伊人 | 午夜精品麻豆 | 91污污视频在线观看 | 青青色影院 | 在线成人免费电影 | 黄色大片av | 天天做夜夜做 | 91在线一区二区 | 国产乱码精品一区二区蜜臀 | 最近中文字幕国语免费高清6 | 亚洲在线色 | 国产最新在线视频 | 国产涩涩在线观看 | 伊人av综合 | 久久国产精品一二三区 | 欧美国产在线看 | 精品国模一区二区 | 国内免费久久久久久久久久久 | 99久久久久久久 | 国产 欧美 在线 | 日韩中字在线观看 | 高清美女视频 | 免费看一级特黄a大片 | 4p变态网欧美系列 | 色999精品| 婷婷九月激情 | 四虎成人精品在永久免费 | 免费一区在线 | 成人小视频在线 | 在线观看国产一区 | 久久成| 亚洲精品乱码久久久一二三 | 日韩综合第一页 | 久久久久免费精品国产小说色大师 | 欧美久久久影院 | 午夜国产在线观看 | 国产福利精品一区二区 | 国产美女视频一区 | 色综合亚洲精品激情狠狠 | 色综合狠狠干 | 久久视讯 | 在线观看 亚洲 | www.夜夜操 | 日本性动态图 | 中文字幕在线资源 | 久久国产网站 | 91黄色成人 | 久久久国产一区二区 | 久久小视频 | 日韩美在线观看 | 97在线精品视频 | 香蕉视频免费在线播放 | 97成人在线观看视频 | 日本在线视频网址 | 日韩性xxx| 国产在线免费av | 国产精品一区久久久久 | 日日日天天天 | 色综合天天干 | 精品产品国产在线不卡 | www.神马久久 | 在线久久 | 中文av一区二区 | 久久这里只有精品1 | 天天艹日日干 | 天天色天天草天天射 | 久久精品999 | 特级黄色电影 | 久久久久久久国产精品 | 91精品久久香蕉国产线看观看 | 亚洲欧洲xxxx| 成人不用播放器 | 国产小视频91 | 99在线视频免费观看 | 99热都是精品 | 一区二区三区污 | 干干干操操操 | 日韩 在线| 亚洲精品在线一区二区 | 中文字幕三区 | 久久tv | 欧美久久久影院 | 97电院网手机版 | 免费黄色av | 国产999视频在线观看 | 久久久久网站 | 日日干夜夜草 | 欧美久久九九 | 66av99精品福利视频在线 | 不卡视频在线看 | 国产日产精品久久久久快鸭 | 亚洲美女视频网 | 韩国av免费看 | 黄色大片免费网站 | 精品影院一区二区久久久 | 亚洲精品国产精品久久99热 | 亚洲人成人在线 | 国产精品久久久久久av | 激情av资源 | 超碰激情在线 | 亚洲1区 在线 | 精品国产视频一区 | 人人插人人澡 | 黄色a大片 | 国产午夜三级一区二区三 | 国产视频一区在线 | 在线视频你懂 | 久久久国产精品网站 | 日韩三级一区 | 美女久久99 | 婷婷丁香激情综合 | 国产精品专区h在线观看 | 人人超在线公开视频 | 日韩欧美极品 | 国产精品综合在线观看 | 最新国产中文字幕 | 亚洲一区欧美激情 | 亚洲成人精品在线 | 成人一级在线观看 | 在线观看av的网站 | 欧美激情精品久久 | 99久久精品免费看国产一区二区三区 | 久久国产精品一二三区 | 欧美日韩免费在线观看视频 | 亚洲国产成人精品电影在线观看 | 久久免费视频网站 | 欧美91精品 | 国产91精品一区二区麻豆亚洲 | 久久婷婷精品视频 | 日韩,中文字幕 | 亚洲理论电影网 | 91精品蜜桃| 精品福利网 | 天天综合网在线 | 人人爽人人爽人人爽 | 911香蕉| 夜夜躁狠狠躁日日躁 | 亚洲乱码国产乱码精品天美传媒 | 91免费版在线观看 | 国产亚州av | av一级片网站 | 在线观看91久久久久久 | 91精品91 | 日韩精品无 | 国产中文字幕三区 | 久久久久激情 | 日韩在线电影一区二区 | 美女黄网久久 | 国产剧在线观看片 | 91精品视频免费在线观看 | 午夜精品一区二区三区在线播放 | 麻豆久久一区二区 | 中文字幕在线观看播放 | 亚洲精品在线观看免费 | 久久婷婷色 | 丰满少妇在线观看资源站 | 丁香婷婷深情五月亚洲 | 九九视频精品在线 | 一区中文字幕电影 | 久久精品官网 | 欧美日韩一区二区免费在线观看 | 国产成人黄色在线 | 国产成人免费观看久久久 | 久久激情片 | 国产精品免费视频一区二区 | 久久av影视 | 美女视频永久黄网站免费观看国产 | 狠狠色丁香婷婷综合久小说久 | 成人香蕉视频 | 欧美三级高清 | 国产精品欧美久久久久天天影视 | av中文在线播放 | 天天干天天想 | 欧美一级网站 | 亚洲特级毛片 | 玖玖视频免费在线 | 伊人影院99| 日韩欧美国产激情在线播放 | 中文在线免费一区三区 | 国产精品久久久免费 | 色噜噜噜 | www.五月婷 | 久久久精品国产免费观看一区二区 | 日日夜夜精品免费 | 成 人 a v天堂 | 中文字幕高清免费日韩视频在线 | 中文在线免费看视频 | 亚洲极色 | 欧美精品国产精品 | 亚洲精品国偷拍自产在线观看 | 2021久久 | 国产精品av免费在线观看 | 国产打女人屁股调教97 | 91九色丨porny丨丰满6 | 国产一区二区三区高清播放 | 国产精品视频一二三 | 美女精品国产 | 国产一区二区精品久久 | 成人h电影 | av先锋影音少妇 | 天堂网一区二区 | 成人在线播放网站 | 韩国三级一区 | 五月天视频网站 | 超碰97在线资源站 | 国产中文视频 | 丁香免费视频 | 日本久久91 | 久久av免费观看 | 久久免费精品 | 国产一级a毛片视频爆浆 | 天堂网在线视频 | 91成人精品视频 | 五月婷婷丁香综合 | 免费av网址在线观看 | 久久久国产精品麻豆 | 激情九九 | 天天干天天草天天爽 | 99精品国产一区二区三区不卡 | 91精品国自产在线偷拍蜜桃 | 玖玖在线播放 | 久久国产精品第一页 | 操操操夜夜操 | 草久久影院 | 国内精品视频在线播放 | 亚洲精品永久免费视频 | 四虎永久精品在线 | 婷婷色在线观看 | 一区二区不卡 | 1024在线看片| 日韩高清不卡一区二区三区 | 九九视频免费观看视频精品 | 国产国语在线 | 成人在线视频网 | 日本精品视频免费观看 | 91视频高清完整版 | 亚洲第一伊人 | 午夜精品久久久久久久99 | 狠狠插天天干 | www欧美日韩 | 精品夜夜嗨av一区二区三区 | 国产免费叼嘿网站免费 | 久久久久久久久久久黄色 | 91精品欧美 | 午夜久久福利视频 | 欧美综合在线观看 | 欧美精品v国产精品v日韩精品 | 一区二区三区在线观看 | 日本黄色大片免费看 | 色999五月色| 精品国产一区二区三区久久久久久 | 午夜精品久久久 | 色搞搞 | 99久久日韩精品免费热麻豆美女 | 欧美色操 | 亚洲综合国产精品 | 亚洲精品资源在线观看 | 欧美激情综合五月色丁香 | av7777777 | 欧美日韩三级 | 摸bbb搡bbb搡bbbb | 欧美精品三级 | 色综合天天色综合 | 97精品国产97久久久久久 | 欧美性生交大片免网 | www.色的| 久久精品亚洲综合专区 | 色诱亚洲精品久久久久久 | 欧美日韩国产精品爽爽 | 日韩av一区二区三区在线观看 | 一本一本久久a久久精品综合 | 91在线看免费 | 波多在线视频 | 玖玖在线观看视频 | 免费国产在线精品 | www.五月天婷婷 | 欧美大码xxxx | 国产字幕av | 欧美色精品天天在线观看视频 | 免费在线国产 | 69精品在线 | 天天拍天天草 | 国产在线小视频 | 激情久久一区二区三区 | 免费观看黄 | 国产精品美女免费 | 国产免费一区二区三区最新 | av观看免费在线 | 中文字幕精品www乱入免费视频 | 一区三区视频在线观看 | 久久黄色小说 | 欧美人牲| 69av久久| 精品999| a视频在线观看免费 | 亚洲91精品在线观看 | 一区二区三区久久 | 97天天干 | 日韩在线观看视频中文字幕 | 99久久99久久综合 | 亚洲视频大全 | 国产亚洲人成网站在线观看 | 天天操天天操一操 | 亚洲激情综合 | 狠狠色香婷婷久久亚洲精品 | 四虎永久免费在线观看 | 日韩美av在线 | 久久国产精品久久w女人spa | 亚洲精品色视频 | 国内精品久久久久久久久久久久 | 在线小视频国产 | 日韩电影在线观看一区二区 | 亚洲资源一区 | 岛国精品一区二区 | 探花视频在线观看免费版 | 精品国产欧美 | 国产精品久久久久久久久免费 | 深爱激情综合 | 久久久精华网 | 亚洲精品成人在线 | 精品一区二区精品 | 日韩激情在线 | 国产福利91精品一区 | 久草久草久草久草 | www.人人草| 亚洲一级国产 | 久久不卡av | 精品免费99久久 | 久草免费在线 | 性色av免费看| 激情欧美一区二区免费视频 | 99re中文字幕 | 欧美成年人在线视频 | 久久精品九色 | 国产精品久久久久久久久久久久午夜片 | 久久乐九色婷婷综合色狠狠182 | 狠狠操操| 97电影院在线观看 | 国产精品麻豆欧美日韩ww | 色婷婷在线视频 | 欧美精品一区二区蜜臀亚洲 | 国产在线播放一区二区三区 | 亚洲无毛专区 | 黄色国产高清 | 精品亚洲成a人在线观看 | 精品国产一区二区三区四 | 亚洲高清视频一区二区三区 | 欧美一级片在线播放 | 在线免费观看亚洲视频 | 成年人在线观看网站 | 久草在线免费资源 | 亚洲国产欧美一区二区三区丁香婷 | 欧美日本国产在线观看 | 中文在线8新资源库 | 国产亚洲欧美在线视频 | 日韩一区二区三区高清在线观看 | 中文字幕日韩一区二区三区不卡 | 久久国产精品一二三区 | 天天天天天干 | 五月天视频网站 | 天天操天天干天天插 | 久久久久免费网站 | 亚洲精品国产精品乱码在线观看 | 午夜电影 电影 | 夜夜躁日日躁狠狠久久av | 在线观看免费一级片 | 国产伦精品一区二区三区四区视频 | 久久伊人精品一区二区三区 | 天天干天天干天天色 | 国产69久久| 国产高清日韩欧美 | 亚洲码国产日韩欧美高潮在线播放 | 特级毛片在线免费观看 | 在线免费观看黄 | 美女免费视频一区 | 亚洲精品国产综合久久 | 日韩首页 | 精品久久久久久亚洲综合网 | 国产精品一区二区久久 | 日韩欧美一区二区在线播放 | 婷婷免费视频 | 1000部18岁以下禁看视频 | 中文字幕在线播放日韩 | 国内一区二区视频 | 久久永久免费 | 国产美女网站视频 | 成人在线观看你懂的 | 综合网在线视频 | 麻豆视频在线 | 免费在线观看成人小视频 | 在线免费观看国产黄色 | 99精品国产在热久久下载 | 久久久久国产精品www | 亚洲波多野结衣 | 国产成人在线免费观看 | 国产一级精品绿帽视频 | 欧美国产日韩一区二区三区 | 国产精品一区二区久久精品爱微奶 | 在线精品在线 | 日韩免费电影网站 | 日本公乱妇视频 | 98涩涩国产露脸精品国产网 | 国产精品精品久久久 | 中文字幕在线观看免费高清完整版 | 日韩二区三区 | 91香蕉亚洲精品 | 九七视频在线 | 精品国产精品久久一区免费式 | 久久久国产一区二区三区 | 久久精品国产亚洲精品2020 | 久久草在线视频国产 | 天天操天天色天天射 | 日韩一区二区三区不卡 | 日本最新中文字幕 | 九九综合久久 | 91久久国产综合精品女同国语 | 国产中文自拍 | 免费福利在线 | 国产精品入口久久 | 日韩视频中文字幕 | 99视频在线看 | 精品久久网 | 成人高清在线观看 | 一级电影免费在线观看 | 精品一区二区在线观看 | 久久久国产精品电影 | 久久久久久综合网天天 | 在线观看免费视频 | 色视频在线看 | 国产四虎在线 | 亚洲国产精品久久久久久 | 五月婷婷综合在线观看 | 中文字幕日韩伦理 | 9ⅰ精品久久久久久久久中文字幕 | 久草精品视频在线播放 | 久久精品99久久久久久 | 在线天堂中文www视软件 | 精品久久久久久久久久久院品网 | 国产成人一区三区 | 国产欧美三级 | av观看在线观看 | 天天射天天舔天天干 | 免费99精品国产自在在线 | 久久视频免费在线观看 | 麻豆免费在线视频 | 亚洲午夜小视频 | 日韩av偷拍 | www国产亚洲 | 中文字幕日韩国产 | 91精彩视频在线观看 | 成人av地址| 国产精品一区二区av日韩在线 | 国产黄色在线观看 | 狠狠色丁香久久综合网 | 三级黄色欧美 | 亚州精品视频 | 免费午夜网站 | 成年人免费观看在线视频 | 在线观看日韩视频 | 成年人在线观看免费视频 | 日韩午夜电影院 | 免费看的黄色的网站 | 免费男女羞羞的视频网站中文字幕 | 欧美日韩国产mv | 97视频在线 | 欧美色综合 | 久久久久国产一区二区三区 | 国产精品va最新国产精品视频 | 国产一级三级 | 在线播放亚洲激情 | 91九色国产视频 | 日本天天操 | 久久精品国产精品亚洲 | 精品视频国产一区 | 一级欧美黄 | 亚洲精品1234区 | 亚洲闷骚少妇在线观看网站 | av在线影片 | www..com毛片| 国产精品1区2区在线观看 | 中文国产字幕在线观看 | 91精品在线观看视频 | 欧美一级专区免费大片 | 免费看黄视频 | 久久夜色精品国产欧美乱 | 欧美日韩在线观看一区二区三区 | 91精选在线 | 亚洲码国产日韩欧美高潮在线播放 | 中文字幕在线观看三区 | 免费a v在线 | 中文字幕免费在线 | 午夜精品久久久久99热app | 欧美一区二区三区激情视频 | 亚洲成人高清在线 | 天天操天天操天天操天天 | 亚洲涩涩涩 | 亚洲国产精品一区二区久久hs | 91一区啪爱嗯打偷拍欧美 | 欧美亚洲国产精品久久高清浪潮 | 在线免费国产 | 天堂av在线网站 | www.97视频 | 最近中文字幕mv免费高清在线 | 国产精品麻豆视频 | 超碰国产在线观看 | 99国产精品久久久久老师 | 天天操夜夜想 | 国产在线看 | 久久婷婷色综合 | 在线观看一区视频 | 国产一级久久 | 碰碰影院| 97理论片| 91精品国产92久久久久 | 五月婷婷激情综合 | 久久免费视频一区 | 精品主播网红福利资源观看 | 欧洲高潮三级做爰 | 91粉色视频 | av成年人电影 | 国产精品电影在线 | 在线观看黄色大片 | 99精品在线播放 | 国内小视频 | 免费一级片视频 | 国产精品成人av久久 | 亚洲区精品 | 国产高清免费视频 | 国外av在线 | 国产精品一区二区美女视频免费看 | 日韩a免费| av中文字幕在线观看网站 | 99视频精品在线 | 91麻豆精品国产91久久久更新时间 | 在线播放 日韩专区 | 久久夜色网 | 超碰公开在线观看 | 美女网站色 | 人人看人人爱 | 国产精品久久久久久久久久久久 | 激情婷婷久久 | 欧美激情视频一区二区三区 | 在线视频1卡二卡三卡 | 日本在线观看视频一区 | 黄色中文字幕在线 | 久久天天躁夜夜躁狠狠85麻豆 | 天天干 夜夜操 | 天天躁天天狠天天透 | 亚洲国产成人精品电影在线观看 | 91豆花在线观看 | 久久夜色精品国产欧美一区麻豆 | 免费福利在线观看 | 国产精品一区二区电影 | 国产一区欧美在线 | 午夜精品久久久 | 国产美女免费观看 | 福利一区在线 | 天天操天天摸天天射 | 免费观看十分钟 | 久久免费a | 久久综合色天天久久综合图片 | 国产精品一区电影 | 国产99在线免费 | 丁香网婷婷 | 精品久久久久久久久中文字幕 | 高潮久久久久久久久 | 欧美在线18 | 欧美色图88 | 综合网天天射 | 久久99免费观看 | 免费精品视频在线观看 | 国产aaa免费视频 | 亚洲成人资源在线 | 在线视频一区二区 | 欧美91在线| 天天操福利视频 | 久久精品一区二区三区四区 | 日韩三区在线观看 | 18国产精品福利片久久婷 | 激情www | 夜夜操网站 | 中文字幕在线观 | 波多野结衣在线视频一区 | 亚洲精品日韩av | 久久久五月天 | 久草视频免费观 | 国产男女无遮挡猛进猛出在线观看 | 在线国产一区二区 | 91视频在线自拍 | 999久久国精品免费观看网站 | 六月婷操| 激情av在线播放 | 亚洲精品黄色 | 免费网站在线观看人 | 最新国产精品久久精品 | 日韩av区 | av青草| 国产高清免费在线观看 | 国产视频一区精品 | 天天干天天做天天爱 | 狠狠色狠狠色综合日日小说 | 美女av免费看| 欧美一级片在线观看视频 | 97视频亚洲 | 四季av综合网站 | 麻豆国产在线播放 | 欧美一级免费在线 | 狠狠操操操 | 国产做aⅴ在线视频播放 | 中文字幕av最新 | 黄色99视频 | 国产护士hd高朝护士1 | 丰满少妇久久久 | 97操操操 | 国产精品福利久久久 | 黄色a一级片 | 丝袜美女视频网站 | 黄色毛片一级 | 久久免费精品一区二区三区 | 激情av在线资源 | 在线观看中文字幕亚洲 | 国产一区免费看 | 国产一区二区久久精品 | 人人爽人人爽av | 午夜精品一二三区 | 午夜精品福利影院 | 91成人网在线 | 久久久久久久久国产 | 中文字幕黄色网址 | 国产又粗又猛又爽又黄的视频免费 | av中文字幕网站 | 欧美日韩国产一二三区 | 成人免费视频在线观看 | 九九免费精品视频 | 激情丁香 | 五月开心六月伊人色婷婷 | 午夜视频在线观看一区 | 一区二区三区在线观看免费视频 | 久久精品久久久久电影 |