JMockit實踐--(2)mock依賴
宣告:
Author:趙志乾
Date:2017-8-5
Declaration:All Right Reserved!!!
1、JMockit庫中的ExpectationsAPI提供了測試用例編寫時對模擬的支援。測試過程中,使用mocking的關注點在於所測程式碼同其所依賴部分的互動呈現出預期行為。一般而言,一個單元的行為被封裝在一個類中,當然,我們也可以將一系列強相關的類作為單元測試中的一個被測單元。
注:並不推薦將單個方法作為一個單獨的測試單元,因為這樣做純屬是為了提高程式碼的覆蓋率。故此,我們並不推薦嚴格意義上的單元測試,也不應該去mock每一個依賴類。即只有當無法使用真正的實現或者使用mock能夠簡化我們的測試時,才去使用模擬。
2、兩個類之間的互動通常表現為方法和建構函式的呼叫。被測類對其依賴方法的一系列呼叫一般會伴隨著引數和返回值得傳遞。此外,也可能需要驗證這一系列呼叫的相對順序。
3、mock的目標是對被測程式碼對其依賴元件的方法和建構函式的呼叫進行模擬,從而將被測程式碼從系統中分離出來。這種模擬方法有如下兩類:
mock欄位:通過註解將依賴宣告為測試類的例項欄位;
mock引數:通過註解將依賴宣告為測試方法的傳入引數;
這兩類形式是等效的。且被mock的型別可以是任意的引用型別:介面、抽象類、final類、註解以及列舉。預設情況下,測試期間mock的型別的所有非私有化方法均會被mock。如果mock的型別是一個類,則它的超類也會遞迴地被mock。因此,繼承的方法也會被mock。對於一個類而言,它的非私有化建構函式也會被mock。
4、當一個方法或建構函式被mock後,測試期間它原來的實現將不再起作用。即呼叫會被重定向到JMockit,從而表現出我們預定義的行為特性。下面給出一個測試結構的示例來說明mock欄位和mock引數以及他們在測試程式碼中的典型使用方式。
// "Dependency" is mocked for all tests in this test class. // The "mockInstance" field holds a mocked instance automatically created for use in each test. @Mocked Dependency mockInstance; @Test public void doBusinessOperationXyz(@Mocked final AnotherDependency anotherMock) { ... new Expectations() {{ // an "expectation block" ... // Record an expectation, with a given value to be returned: mockInstance.mockedMethod(...); result = 123; ... }}; ... // Call the code under test. ... new Verifications() {{ // a "verification block" // Verifies an expected invocation: anotherMock.save(any); times = 1; }}; ... }
測試方法被執行時,位於測試方法引數列表中的mock引數,會被JMockit自動建立和初始化,所以mock引數永遠不會為null;而對於mock欄位的例項,其也會被JMockit自動建立和賦值。
注:本部落格中的例項程式碼均來自於JMockit官方教程。