原文地址:https://www.codeproject.com/articles/516360/mockito-a-great-mock-framework-for-java-developmen
Mockito是一個諷刺的架構,味道非常好。 它允許您使用乾淨簡單的API編寫漂亮的測試。
介紹
這個藝術將展示mock架構的一些基本概念,為什麼我們應該使用它,並演繹一個在Java中應用Mockito的簡單方法。
Mock的概念
在軟體開發世界之外,術語“ mock ”意味著模仿或類比。 因此,“ mock ”可以被認為是一種獨立的,冒名頂生的,或者最常被稱之為軟體開發,一種fake 。
假貨經常被用作待測類的依賴關係。
條款和定義 |
依賴關係 - 依賴關係是指應用程式中的一個類別依賴於另一個類來執行其預期功能。 依賴關係通常儲存在依賴類中的執行個體變數中。 |
|
被試課程 - 在進行單元測試時,術語“單元”通常是指一個單獨的類,特別是測試寫入的類。 因此,被測試類別是正在測試的應用程式類。 |
為什麼類比。
當我們學習編程時,我們的對象通常是自包含的。 任何你好的世界都沒有依賴於外部類(System.out),也不會在學習語言的過程中寫入許多其他類。 然而,在現實世界中,軟體具有依賴性。 我們有依賴於Data Access Objects(DAO)的服務和服務的操作類,列表繼續。
單元測試的想法是我們要測試我們的代碼而不測試依賴。 此測試允許您驗證正在測試的代碼是否工作,而不管其是否依賴。 理論是,如果我寫的代碼按照設計工作,我的依賴關係按照設計工作,那麼他們應該按照設計一起工作。 下面的代碼將是一個例子: Hide Copy Code
import java.util.ArrayList;public class Counter { public Counter() { } public int count(ArrayList items) { int results = 0; for(Object curItem : items) { results ++; } return results; }}
我知道上面的例子就像你所得到的一樣簡單,但是它說明了一點。 如果您想測試方法計數,您將在測試中寫入,以解決計數方法的工作原理。 您不是試圖測試ArrayList的工作原理,因為您假設它已經過測試並按照設計工作 。您唯一的目標是測試您對ArrayList的使用。
類比對象背後的概念是我們想要建立一個取代真實對象的對象。 這個類比對象將期望使用某些參數調用某種方法,而在這種情況下, 它將返回一個預期的結果。 什麼是關鍵的Mock概念。
當談到mock時,你只需要3件事情就需要擔心; 扼殺,設定期望和驗證。 某些單元測試情境不涉及任何這些情況,其他單獨測試情境只涉及樁杆,而其他則涉及設定預期和驗證。 存根
Stubbing是告訴你的假的過程,當它與它進行互動時如何表現。 您通常可以存放公用屬性(帶有getter和/或setter的公用屬性)和公用函數。
說到stubbing功能,你通常有很多選擇。 您可能希望返回特定值,拋出錯誤或調度事件。 此外,您可能希望指示函數的行為方式取決於調用方式(即通過匹配傳遞給函數的參數的類型或值)。
如果這聽起來像是很多的工作,它可以是,但它一般不是。 許多mock架構的一個很大的特點是你不需要stub void函數。 您也不必在執行測試過程中儲存任何未被調用的函數或未查詢的屬性。 設定期望
假冒的主要特徵之一就是能夠告訴假冒測試回合時的期望。 例如,您可能希望調用一個特定的函數3次。 你可能期望它永遠不會被調用。 您可能希望它至少被調用兩次,但不要超過5次。 您可能希望使用特定類型的參數或特定值或上述任何組合來調用它。 可能性是無止境的。
設定期望是告訴你假的你會發生什麼的過程。 記住,由於它是假的,實際上沒有發生。 但是,你被測試的班級並不聰明。 從它的角度來看,它調用了這個函數,並期望它做了它應該做的任何事情。
對於什麼是值得的,大多數嘲笑架構可以讓您建立介面或公用類的類比。 您不限於僅僅類比介面。 驗證
設定期望和驗證是並存的。 在調用被測試類別的函數之前,設定期望值。 驗證完成。 所以,首先你設定了期望,然後驗證你的期望是否得到滿足。
從單元測試的角度來看,如果您的期望未得到滿足,則單元測試失敗。 例如,如果您設定了ILoginService.login函數應該使用特定的使用者名稱和密碼一次調用的期望,但是在執行測試期間它並沒有被調用,則該偽造不會被驗證,並且測試失敗。 Mock的好處是什麼。
您可以提前建立測試; TDD
這一個是更強大的好處之一。 如果您建立一個模擬器,您可以在服務建立之前編寫服務測試,使您能夠在開發過程中將測試添加到自動化環境中。 換句話說,Service Mocking可以讓您使用測試驅動開發。
團隊可以並行工作
這與上述類似 為不存在的代碼建立測試。 但是以前的一點是針對開發人員編寫測試,這是針對測試團隊的。 當您沒有任何測試時,團隊如何開始建立測試。 類比它,並對模擬器進行測試。 這意味著當服務準備好進行測試時,QA團隊實際上可以準備一整套測試; 我們沒有停機的時候,一個隊伍等待另一個完成。 這使得嘲弄的財務論據特彆強。
您可以建立概念或示範的證明。
由於Mocks可以(成本最高)能夠實現成本效益,因此可以使用Mocks來建立概念證明,線架構,或作為您正在考慮構建的應用程式的示範。 這是非常強大的,為決定是否繼續開發項目做出決定,但最重要的是為實際設計決策提供了良好的基礎。
您可以編寫測試資源不可訪問
這是不屬於實際利益類別的好處之一,而是作為救生員。 曾經想要測試或使用服務,只是被告知該服務是在防火牆後面,那個防火牆無法為您開啟,或者您被授權使用該防火牆。 當你這樣做時,一個MockService放置在可訪問的地方,包括在你本地的電腦上,是一個救命的人。
模擬器可以交付給客戶
有些情況下,您無法允許訪問外部來源的測試系統(如夥伴或客戶)的原因。 這些原因可以是訪問安全性,資訊敏感性,或只是測試環境可能無法24/7訪問的事實。 在這些情況下 您如何為您的夥伴或客戶提供測試系統以開始開發或測試。 一個簡單的解決方案是從您的網路或客戶自己的網路提供一個類比。 soapUI類比是非常容易部署的,它可以在soapUI中運行,也可以作為.WAR檔案匯出,並放置在您選擇的Java伺服器中。
您可以隔離系統
有時您想測試系統的一部分,而不會影響其他系統組件。 這是因為其他系統會對測試資料增加噪音,使得從收集的資料中得出更好的結論更加困難。 使用mocks,您可以刪除所有的系統,嘲笑所有系統,除了您在測試中需要確定的一個系統。 當進行嘲諷隔離時,這些嘲弄可以做得非常簡單但可靠,快速,可預測。 這給您一個測試環境,您已經刪除了所有隨機行為,具有可重複的模式,並可以很好地監控特定系統。 Mockito架構
Mockito是根據MIT許可證發布的Java開源測試架構。
Mockito通過允許開發人員預先確定被測系統(SUT)的行為來區別於其他嘲笑架構。[4] 對類比對象的批評之一是測試代碼與被測系統的緊密耦合。[5] 由於Mockito試圖通過消除預期的規範來消除預期運行驗證模式[6],所以耦合被減小或最小化。 這個區別功能的結果是更簡單的測試代碼,應該更容易閱讀和修改。 您可以驗證互動: Hide Copy Code
// mock creationList mockedList = mock(List.class);// using mock objectmockedList.add("one");mockedList.clear();// selective and explicit vertificationverify(mockedList).add("one");verify(mockedList).clear();
或存根方法調用 Hide Copy Code
// you can mock concrete class, not only interfacesLinkedList mockedList = mock(LinkedList.class);// stubbing - before executionwhen(mockedList.get(0)).thenReturn("first");// following prints "first"System.out.println(mockedList.get(0));// following prints "null" because get(999) was not stubbed.System.out.println(mockedList.get(999));
使用Mockito的簡單樣本Java代碼
沒有Mock架構
用Mockito架構 步驟1:在Eclipse中建立一個Maven項目
定義pom.xml如下: Hide Shrink Copy Code
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>vn.com.phatbeo.ut.mockito.demo</groupId> <artifactId>demoMockito</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demoMockito</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <sourceDirectory>src</sourceDirectory> <testSourceDirectory>test</testSourceDirectory> <plugins> <plugin>