維基百科對單元測試的定義: 單元測試(英語:Unit Testing)又稱爲模塊測試,是針對程序模塊(軟件設計的最小單位)來進行正確性檢驗的測試工做。程序單元是應用的最小可測試部件。在過程化編程中,一個單元就是單個程序、函數、過程等;對於面向對象編程,最小單元就是方法,包括基類(超類)、抽象類、或者派生類(子類)中的方法。 單元測試的目標是隔離程序部件並證實這些單個部件是正確的。
Mock脫離數據庫 + 不啓動Spring + 優化測試速度 + 不引入項目組件數據庫
單元測試不該該依賴數據,依賴外部服務或組件等,會對其餘數據產生影響的狀況。啓動Spring容器,通常比較慢,可能會啓動消息監聽消費消息,定時任務的執行等,對數據產生影響。編程
Mock測試就是在測試過程當中,對那些當前測試不關心的,不容易構建的對象,用一個虛擬對象來代替測試的情形。網絡
說白了:就是解耦(虛擬化)要測試的目標方法中調用的其它方法,例如:Service的方法調用Mapper類的方法,這時候就要把Mapper類Mock掉(產生一個虛擬對象),這樣咱們能夠自由的控制這個Mapper類中的方法,讓它們返回想要的結果、拋出指定異常、驗證方法的調用次數等等。app
減小單元測試對外部的依賴和反作用,提升單元測試效率函數
若是使用@Mock註解, 必須去觸發所標註對象的建立. 可使用 MockitoRule來實現. 它調用了靜態方法MockitoAnnotations.initMocks(this) 去初始化這個被註解標註的字段.或者也可使用@RunWith(MockitoJUnitRunner.class).單元測試
「when thenReturn」和」when thenThrow」
模擬對象能夠根據傳入方法中的參數來返回不一樣的值, when(….).thenReturn(….)方法是用來根據特定的參數來返回特定的值.測試
咱們也可使用像 anyString 或者 anyInt anyLong any 這樣的方法來定義某個依賴數據類型的方法返回特定的值.優化
「doReturn when」 和 「doThrow when」
doReturn(…).when(…)的方法調用和when(….).thenReturn(….)相似.對於調用過程當中拋出的異常很是有用.而doThrow則也是它的一個變體.this
@Mock:對函數的調用均執行mock(即虛假函數),不執行真正部分。設計
@Spy:對函數的調用均執行真正部分。
@InjectMocks:建立一個實例,簡單的說是這個Mock能夠調用真實代碼的方法,使用@Mock(或@Spy)註解建立的mock將被注入到用該實例中。
Mockito中的Mock和Spy均可用於攔截那些還沒有實現或不指望被真實調用的對象和方法,併爲其設置自定義行爲。兩者的區別在於Mock不真實調用,Spy會真實調用。
@MockBean: 功能同 @Mock, 只是會將實例放入 Spring 容器管理
@SpyBean: 功能同 @Spy, 只是會將實例放入 Spring 容器管理
// 不使用 @SpringBootTest(classes = Application.class) @RunWith(SpringRunner.class) public class ExamAnswerComponentTest { // 建立一個實例,會注入Mock變量 @InjectMocks private ExamAnswerComponent examAnswerComponent = new ExamAnswerComponentImpl(); // 相關操做會被Mock掉 @Mock private ExamAnswerCacheObjectiveDAO examAnswerCacheObjectiveDAO; @Before public void setUp() { // 初始化Mock MockitoAnnotations.initMocks(this); // given...willReturn 指定方法參數,模擬返回值 given(examAnswerCacheObjectiveDAO.selectByBizIdAndPaperAndQuestion(any(), any(), any())) .willReturn(new ExamAnswerCacheObjectivePO()); given(examAnswerCacheObjectiveDAO.insert(any())).willReturn(1); given(examAnswerCacheObjectiveDAO.updateUserAnswerById(any(), any())).willReturn(1); } @Test public void saveOrUpdateAnswerCacheObjective() { ExamAnswerCacheObjectivePO po = new ExamAnswerCacheObjectivePO(); po.setBizId(100000015L); po.setBizType(9); po.setUserAnswer("A"); po.setGroupPaperId(1000320L); po.setQuestionId(1000042L); po.setQuestionType(1); int affect = examAnswerComponent.saveOrUpdateAnswerCacheObjective(po); System.out.println("affect = " + affect); Assert.assertTrue(affect > 0); } }