Mock單元測試

  單元測試的思路是在不涉及依賴的狀況下測試代碼,通常是測試service層的方法,但實際的代碼常會涉及到依賴,一個可行的方法就是使用模擬對象來替換依賴對象。框架

1.使用Mockito生成mock對象

  Mockito 是一個流行 mock 框架,能夠和JUnit結合起來使用。Mockito 容許你建立和配置 mock 對象。使用Mockito能夠明顯的簡化對外部依賴的測試類的開發。maven

通常使用 Mockito 須要執行下面三步函數

  • 模擬並替換測試代碼中外部依賴。單元測試

  • 執行測試代碼測試

  • 驗證測試代碼是否被正確的執行this

 1.1.在maven中添加mockito依賴

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <scope>test</scope>
        </dependency>

1.2.靜態引用

若是在代碼中靜態引用了org.mockito.Mockito.*;,那你你就能夠直接調用靜態方法和靜態變量而不用建立對象,譬如直接調用 mock() 方法。spa

1.3.使用 Mockito 建立和配置 mock 對象

Mockito 還支持經過 @Mock 註解的方式來建立 mock 對象.net

使用註解,那麼必需要實例化 mock 對象。Mockito 在遇到使用註解的字段的時候,會調用 MockitoAnnotations.initMocks(this) 來初始化該 mock 對象。另外也能夠經過使用@RunWith(MockitoJUnitRunner.class)來達到相同的效果。code

註解對象

  • @Mock:建立 mock 對象
  • @InjectMocks 在 Mockito 中進行依賴注入

調用方法

when(…​.).thenReturn(…​.)能夠被用來定義當條件知足時函數的返回值,若是你須要定義多個返回值,能夠屢次定義。當你屢次調用函數的時候,Mockito 會根據你定義的前後順序來返回返回值。Mocks 還能夠根據傳入參數的不一樣來定義不一樣的返回值。譬如說你的函數能夠將anyString 或者 anyInt做爲輸入參數,而後定義其特定的放回值。

自定義方法的返回值

Mockito.when(方法).thenReturn(返回值)        

Mockito.when(方法).thenReturn(返回值1).thenReturn(返回值2)

無返回值

對於無返回值的函數,咱們可使用doReturn(…​).when(…​).methodCall來得到相似的效果。例如咱們想在調用某些無返回值函數的時候拋出異常,那麼可使用doThrow 方法。

以下所示:

Mockito.doThrow(new IOException()).when(mockStream).close()   

僅調用方法,但啥也不作

Mockito.doNothing().when(tagRepository).deleteByTagId(1) 

注:tagRepository有一個方法是 deleteByTagId(int tagId) 

驗證 query 方法是否被 MyDatabase 的 mock 對象調用

verify(databaseMock).query("* from t");

查看在傳入參數爲12的時候方法是否被調用
verify(test).testing(Matchers.eq(12));

方法是否被調用兩次
verify(test, times(2)).getUniqueId();

verify(mock, never()).someMethod("never called");
verify(mock, atLeastOnce()).someMethod("called at least once");
verify(mock, atLeast(2)).someMethod("called at least twice");
verify(mock, times(5)).someMethod("called five times");
verify(mock, atMost(3)).someMethod("called at most 3 times");

1.4.mockito的限制

下面三種數據類型則不可以被測試

  • final classes

  • anonymous classes

  • primitive types

 Mockito 不可以 mock 靜態方法,所以咱們可使用 Powermock

2.powerMock

powerMock能mock靜態、final、私有方法等

PowerMock支持EasyMock和Mockito。

2.1PowerMock有兩個重要的註解

@RunWith(PowerMockRunner.class)
@PrepareForTest( { YourClassWithEgStaticMethod.class })
  若是測試用例裏沒有使用註解@PrepareForTest,那麼能夠不用加註解@RunWith(PowerMockRunner.class),反之亦然。當你須要使用PowerMock強大功能(Mock靜態、final、私有方法等)的時候,就須要加註解@PrepareForTest。

 2.2基本用法

詳見 http://blog.csdn.net/knighttools/article/details/44630975

2.2.1和普通Mock的用法相同

PowerMockito.when(file.exists()).thenReturn(true);

2.2.2 Mock方法內部new出來的對象

File file = PowerMockito.mock(File.class);
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.whenNew(File.class).withArguments("bbb").thenReturn(file);
PowerMockito.when(file.exists()).thenReturn(true);

2.2.3 Mock普通對象的final方法

ClassDependency depencency = PowerMockito.mock(ClassDependency.class);
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.when(depencency.isAlive()).thenReturn(true);

2.2.4.Mock普通類的靜態方法

PowerMockito.mockStatic(ClassDependency.class);
PowerMockito.when(ClassDependency.isExist()).thenReturn(true);

2.2.5 Mock 私有方法

ClassUnderTest underTest = PowerMockito.mock(ClassUnderTest.class);
PowerMockito.when(underTest.callPrivateMethod()).thenCallRealMethod();
PowerMockito.when(underTest, "isExist").thenReturn(true);

2.2.6. Mock系統類的靜態和final方法

ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("aaa")).thenReturn("bbb");

2.2.7 驗證方法

(1) 驗證靜態方法:
PowerMockito.verifyStatic();
Static.firstStaticMethod(param);
(2) 擴展驗證:
PowerMockito.verifyStatic(Mockito.times(2)); // 被調用2次

Static.thirdStaticMethod(Mockito.anyInt()); // 以任何整數值被調用

相關文章
相關標籤/搜索