版本歷史html |
|||
-android |
-數據庫 |
-框架 |
-ide |
該教程主要講解 Mockito 框架在Eclipse IDE 中的使用 單元測試
目錄 測試
使用 Mockito 進行測試 1 this
1. 需求知識 2 google
2. 使用 存根(Stub) 和 模擬對象(Mock Object) 進行測試 2
2.2. 存根(Stub) vs. 模擬對象 (Mock) 2
該教程須要理解單元測試和熟悉JUnit 框架的使用。
若是您不熟悉 JUnit,請閱讀 JUnit 教程。
一個單元測試須要在隔離的環境下執行。若是能夠的話須要消除其餘依賴的服務影響。但實際上,軟件中是充滿依賴關係的.咱們會基於service類寫操做類,而service類又是基於數據訪問類(DAOs)的,依次下去.
爲了解決這個問題, 可使用 存根 (Stub) 或者 模擬 (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();
}
}
存根和模擬對象均可以傳遞給其餘的對象進行測試。你的一些單元測試能夠測這些類的正確性等。利用存根對象或者模擬對象能夠保證測試過程當中不受到其餘的影響。
存根對象須要自定義實現方法;
模擬對象只須要更少的代碼和簡單的配置。
如下的內容將詳細介紹模擬對象的使用方法。
Mock 對象容許你對行爲進行測試。有一些測試不須要驗證結果,可是須要檢查某些方法是否被正確的參數調用過。這種測試爲行爲測試。
狀態測試只是關注與結果是否正確,而行爲測試可以判斷一個應用調用結構以及層次。
大家可使用Mock 框架來生成模擬對象。Mock 框架容許你在運行期間建立對象,而且定義它的一些行爲。
一個典型的例子就是使用模擬對象來模擬數據庫DAO層。在生產環境上是使用運行的數據庫,可是在單元測試環境中徹底能夠用模擬對象來模擬數據,確保單元測試的正確條件。這樣就不須要依賴於外部的數據。
比較流行的模擬框架有 EasyMock、jMock 和 Mockito。下面的列表是這些框架的連接。
# jMock
http://jmock.org/
# EasyMock
http://easymock.org/
# Mockito
http://code.google.com/p/mockito/
Mockito 是比較流行的模擬框架,能夠與JUnit 聯合起來測試。它容許你進行建立和配置模擬對象。
Mockito的官方網站: 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()
Mockito 如下的類型不能進行構造:
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 結構
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 ) );
}
@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 ) );
}
Mockito 一樣也能夠在安卓平臺上進行測試。
在 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 。
感謝閱讀該教程:
Mockito 項目主頁