關於單元測試的那些事兒,Mockito 都能幫你解決

摘要:相信每一個程序猿在寫Unit Test的時候都會碰到一些令人頭疼的問題:如何測試一個rest接口;如何測試一個包含客戶端調用服務端的複雜方法;如何測試一個包含從數據庫讀取數據的複雜方法。。。這些問題mockito都可以幫我們輕鬆地解決。Mockito是啥?Mockito 是一個強大的用於 Java 開發的模擬測試框架, 通過 Mockito 我們可以創建和配置 Mock 對象, 進而簡化有外...

本文分享自華爲雲社區《mockito——讓你輕鬆地進行單元測試的強大工具》,作者:數據湖愛好者。

相信每一個程序猿在寫Unit Test的時候都會碰到一些令人頭疼的問題:如何測試一個rest接口;如何測試一個包含客戶端調用服務端的複雜方法;如何測試一個包含從數據庫讀取數據的複雜方法。。。這些問題Mockito都可以幫我們輕鬆地解決。

Mockito是啥?

Mockito 是一個強大的用於 Java 開發的模擬測試框架, 通過 Mockito 我們可以創建和配置 Mock 對象, 進而簡化有外部依賴的類的測試。簡單來說,創建mock對象之後,這個對象裏面的方法是怎麼實現的可以不用去關心,我們只需要給這個方法定義一個輸入、輸出即可。

什麼情況下使用Mockito:

假設現在要測試method A, method A裏面又依賴Method B、Method C、Method D,而依賴的這3個method又不好去構建(如ObsClient需要真實AK SK,HttpClient需要構建客戶端與服務器,Database相對好構建,但是假設Method C只是從table1、table2聯合查詢,你還得分別往table1、table2 insert數據,很繁瑣),這時候可以考慮Mockito進行優雅測試,當然如果你想去構建真實的測試場景,未免有點捨本逐末了~~~

Mockito的使用:

1、引進依賴

Maven依賴如下:

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>1.10.19</version>
  <scope>test</scope>
</dependency>

代碼中:import org.mockito.Mockito

2、創建Mock對象

這裏需要注意的是scala中只能對伴生對象或者Class創建mock對象,不能直接對Object創建mock對象。Scala中使用Mockito.mock(classOf[…])來創建mock對象

class VpcClient {

def getRouteTable(projectId: String, token: String, url: String): Seq[RouteTable] = {

  val header = Map(RequestAttributes.X_AUTH_TOKEN -> token,

    "Content-Type" -> MediaType.APPLICATION_JSON)

  val response = restClient.get(url, header)
}
}
object VpcClient {

  private lazy val _instance: VpcClient = new VpcClient(conf)

  private var mockClient: VpcClient = _

  def getInstance(): VpcClient = {

    // Keep original logic for other ut, which didn't set mock client.

    if (RuntimeEnvironment.isTesting && null != mockClient) {

      return mockClient

    }

    _instance

  }

  // only used for UT

  def setMockClient(vpcClient: VpcClient): Unit = {

    mockClient = vpcClient

  }

}

舉個例子,現在對VpcClient進行mock,從而可以調用VpcClient裏面的getRouteTableList方法。

class UtilSuite {
  val vpcClient = Mockito.mock(classOf[VpcClient])

VpcClient.setMockClient(vpcClient)
}

3、配置Mock對象

Mockito.doReturn(routeTableInfo).when(vpcClient).getRouteTable(projectId, token,url)

當我們有了一個 Mock 對象後, 我們可以調用對象的方法,並且使用Mockito.doReturn().when().method,來設置當調用method時,在某輸入下返回某輸出。這裏的輸入是要與 method真實的入參一致的,輸出也是要與method真實的返回參數一致。

class UtilSuite {
  val vpcClient = Mockito.mock(classOf[VpcClient])

VpcClient.setMockClient(vpcClient)


val projectId = "projectId"

val token = "token"

val url= "url"

val routeTableInfo = new RouteTableInfo
 
Mockito.doReturn(routeTableInfo).when(vpcClient).getRouteTable(projectId, token, url)
}

總結:

上面講了Mockito的使用場景,以及scala中怎麼使用Mockito創建mock對象。與java中使用Mockito有些許的差別,這些如果感興趣的話都可以參考下官方文檔:

 

獲取更多 AI 相關數據、算法、模型等 AI 資產,請點擊“瞭解更多”,AI Gallery等您!

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章