tanyuanji@126.com
版本歷史 |
|||
- |
- |
- |
- |
使用 Mockito 進行測試
該教程主要講解 Mockito 框架在Eclipse IDE 中的使用
目錄
2. 使用 存根(Stub) 和 模擬對象(Mock Object) 進行測試 2
2.2. 存根(Stub) vs. 模擬對象 (Mock) 2
1. 需求知識
該教程需要理解單元測試和熟悉JUnit 框架的使用。
如果您不熟悉 JUnit,請閱讀 JUnit 教程。
2. 使用 存根(Stub) 和 模擬對象(Mock Object) 進行測試
2.1. 為什么需要模擬?
一個單元測試需要在隔離的環境下執行。如果可以的話需要消除其他依賴的服務影響。但實際上,軟件中是充滿依賴關系的.我們會基於service類寫操作類,而service類又是基於數據訪問類(DAOs)的,依次下去.
為了解決這個問題, 可以使用 存根 (Stub) 或者 模擬 (Mock) 對象的方法進行測試。
2.2. 存根(Stub) vs. 模擬對象 (Mock)
存根(Stub)類是實現了一個接口或者抽象類的類,可以在測試過程中使用該類,例如:
package cn.nsccsz.stub;
public class TestStub {
static interface USB {
void work();
}
static class Mp3Stub implements USB {
@Override
public void work() {
// code.
}
}
static class Mp4Stub implements USB {
@Override
public void work() {
// code.
}
}
}
一個模擬對象(mock object)是一個接口或者抽象類的虛擬實現。例如:
public class TestMock {
static interface USB {
void work();
}
@Test
public void testMockObject() {
USB usb = Mockito.mock( USB.class );
usb.work();
}
}
存根和模擬對象都可以傳遞給其他的對象進行測試。你的一些單元測試可以測這些類的正確性等。利用存根對象或者模擬對象可以保證測試過程中不受到其他的影響。
存根對象需要自定義實現方法;
模擬對象只需要更少的代碼和簡單的配置。
以下的內容將詳細介紹模擬對象的使用方法。
2.3. 行為測試 vs. 狀態測試
Mock 對象允許你對行為進行測試。有一些測試不需要驗證結果,但是需要檢查某些方法是否被正確的參數調用過。這種測試為行為測試。
狀態測試只是關注與結果是否正確,而行為測試能夠判斷一個應用調用結構以及層次。
2.4. 生成模擬對象
你們可以使用Mock 框架來生成模擬對象。Mock 框架允許你在運行期間創建對象,並且定義它的一些行為。
一個典型的例子就是使用模擬對象來模擬數據庫DAO層。在生產環境上是使用運行的數據庫,但是在單元測試環境中完全可以用模擬對象來模擬數據,確保單元測試的正確條件。這樣就不需要依賴於外部的數據。
3. 模擬框架( Mock Framework)
比較流行的模擬框架有 EasyMock、jMock 和 Mockito。下面的列表是這些框架的鏈接。
# jMock
http://jmock.org/
# EasyMock
http://easymock.org/
# Mockito
http://code.google.com/p/mockito/
4. Mockito
4.1. 使用 Mockito 模擬對象
Mockito 是比較流行的模擬框架,可以與JUnit 聯合起來測試。它允許你進行創建和配置模擬對象。
Mockito的官方網站: Mockito 主頁.
4.2. 使用 Mockito
Mockito 支持使用 mock() 靜態方法創建模擬對象。
同樣也支持 @Mock注解方式,如果使用注解的方式,需要使用在初始化方法調用 MockitoAnnotation.InitMock( this ) 方法
For example, the following code demonstrate the usage of Mockito to test a class called ClassToTest.
例如,下面的例子就是使用 Mockito 進行對類 ClassToTest 的單元測試。
public class MockitoTest {
@Mock
MyDatabase databaseMock;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void testQuery() {
// 需要測試的類
ClassToTest t = new ClassToTest(databaseMock);
// 調用方法
boolean check = t.query("* from t");
// 驗證結果
assertTrue(check);
// 模擬對象是否調用了該方法
Mockito.verify( databaseMock ).query("* from t");
}
提示
可以使用靜態導入方法調用方法 mock()
4.3. Mockito的限制
Mockito 以下的類型不能進行構造:
-
終態類(final classes)
-
匿名類(anonymous classes)
-
基本數據類型(primitive types)
4.4. 模擬對象的配置
Mockito 可以使用 verify() 方法來確認某些方法是否被調用過.
when(....).thenReturn(....) 結構可以為某些條件給定一個預期的返回值.
@Test
public void testList() {
List mock = Mockito.mock( List.class );
Mockito.when( mock.get( 0 ) ).thenReturn( 1 );
assertEquals( "預期返回1", 1, mock.get( 0 ) );
}
同樣可以使用doReturn(object).when(kdskfsk).methodCall 結構
4.5. 驗證模擬對象的行為
Mockito 跟蹤了所有的方法調用和參數的調用情況。verify()可以驗證方法的行為。
查看下面的例子:
@Test
public void testMap() {
Map mock = Mockito.mock( Map.class );
Mockito.when( mock.get( "city" ) ).thenReturn( "深圳" );
// test code
assertEquals( "城市測試", "深圳", mock.get( "city" ) );
Mockito.verify(mock).get( Matchers.eq( "city" ) );
Mockito.verify( mock, Mockito.times( 2 ) );
}
4.6. Spy
@Spy 或者方法 spy() 可以包含一個真實的對象. 每次調用,除非特出指定,委托給改真實對象的調用.
@Test
public void testSpy() {
// Lets mock a LinkedList
List list = new LinkedList();
list.add( "yes" );
List spy = Mockito.spy(list);
//You have to use doReturn() for stubbing
assertEquals( "yes", spy.get( 0 ) );
Mockito.doReturn("foo").when(spy).get(0);
assertEquals( "foo", spy.get( 0 ) );
}
@Test( expected = IndexOutOfBoundsException.class)
public void testSpy2() {
// Lets mock a LinkedList
List list = new LinkedList();
List spy = Mockito.spy(list);
// this would not work
// real method is called so spy.get(0)
// throws IndexOutOfBoundsException (list is still empty)
Mockito.when(spy.get(0)).thenReturn("foo");
assertEquals( "foo", spy.get( 0 ) );
}
5.1. 在 Android 使用 Mockito
Mockito 同樣也可以在安卓平台上進行測試。
5.2. 安裝
在 Android 測試項目中使用 Mockito。添加下面的包到Android 測試項目的 libs 目錄
https://mockito.googlecode.com/files/mockito-all-1.9.5.jar
http://dexmaker.googlecode.com/files/dexmaker-1.0.jar
http://dexmaker.googlecode.com/files/dexmaker-mockito-1.0.jar
After you make the libraries available you can use Mockito in your tests.
接下來可以在你的測試項目中使用 Mockito 。
6. 感謝
感謝閱讀該教程:
7. 鏈接和參考
7.1. Mockito 相關鏈接
Mockito 項目主頁
