使用Mockito進(jìn)行單元測(cè)試

一、使用JUnit + Mockito進(jìn)行單元測(cè)試

Java中的Mock工具有很多,比如Mockito, jMock, EasyMock等,在這里我們只說下Mockito,因?yàn)槠渌奈乙矝]用過:-D
下面省去怎么引入mockito的步驟,希望可以用不到1h的時(shí)間,讓大家可以使用Mockito寫出期望的單測(cè)。

二、實(shí)戰(zhàn)mockito

mockito是一款開源的測(cè)試框架,可以方便地通過mock(模擬)方式進(jìn)行測(cè)試驗(yàn)證??梢院芊奖愕馗鶭Unit結(jié)合起來用。為了更好地使用mockito,我們先來了解下mockito中的幾個(gè)核心概念。

2.1 mock

mock,就是偽造一個(gè)待測(cè)試的對(duì)象,可以隨意擺布,讓它干啥就干啥。
mockito中,可以通過TestClass mockObject = mock(TestClass.class)來創(chuàng)建一個(gè)偽造的對(duì)象。
如果你調(diào)用mockObject中的方法,則什么事情都不會(huì)做,如果對(duì)應(yīng)方法有返回值的話,那就返回返回類型在JAVA中的默認(rèn)值。比如如果方法的返回值類型是boolean則返回false,如果返回值類型是String則返回null, List返回[]等

2.2 stub樁

樁(Stub),就是把要調(diào)用的方法模擬掉,讓方法按照我們的期望行動(dòng)。一般樁的目的,有三種

  1. doNothing : 啥也不做
  2. doReturn : 返回具體值
  3. doThrow: 拋出異常

對(duì)于doReturn,有兩種實(shí)現(xiàn)方法,

  1. when(mockObject.invokeMethod(...params)).thenReturn(...) : 會(huì)真正執(zhí)行invokeMethod內(nèi)的邏輯,只是返回值會(huì)為設(shè)定的返回值。
  2. doReturn(...).when(mockObject).invokeMethod(...params) : 不會(huì)真正執(zhí)行invokeMethod,只返回設(shè)定值。

doThrow邏輯跟doReturn一樣。

2.2 mock V.S. spy

我們?cè)谑褂胢ockito過程中,可以以mock的方式,也可以以spy的方式把實(shí)際的動(dòng)作給mock掉。如

TestClass object = mock(TestClass.class); // mock
TestClass object = spy(TestClass.class); // spy

這兩種方式有什么區(qū)別呢? 簡(jiǎn)而言之
mock就是對(duì)象是完完全全假的對(duì)象,其中所有的方法都會(huì)以樁的方式來執(zhí)行。
spy,又稱部分mock,如果設(shè)置了樁,則使用樁的返回值;如果未設(shè)置樁,則調(diào)用對(duì)象真實(shí)的方法

當(dāng)然你也可以指定mock對(duì)象具體方法的行為,在2.2節(jié)已經(jīng)講過。

2.3 使用mock class, 導(dǎo)致@Autowired的bean注入為Null

在spring的項(xiàng)目中,我們通常會(huì)在類中通過注解的方式注入對(duì)象,比如

public class PersonService {
    @Autowired
    private PersonDao personDao;
    
    public String getPersonName(Long id) {
        return personDao.getPersonName(id);
    }
}

如果你在mockito的單測(cè)中,直接寫PersonService personService = mock(PersonService.class); 那在真正執(zhí)行g(shù)etPersonName(id)這個(gè)時(shí)候,對(duì)于personDao這個(gè)對(duì)象,是null。
原因就是單測(cè)對(duì)象被Mock掉之后,其中注入的對(duì)象spring是感知不到的。這個(gè)就跟我們自己通過new TestClass()方式無法注入@Autowired對(duì)象一個(gè)邏輯。

解決方案就是利用@InjectMocks 進(jìn)行注入,注意在單測(cè)跑之前需要調(diào)用MockitoAnnotations.initMocks(this);

具體可以參考: https://dzone.com/articles/use-mockito-mock-autowired

2.4 利用verify做驗(yàn)證

對(duì)于Mock的對(duì)象,由于我們就是為了把實(shí)際的操作給mock掉,那mockito怎么驗(yàn)證測(cè)試是否啟動(dòng)成功? 在mockito中,可以記錄每次調(diào)用的方法以及對(duì)應(yīng)的參數(shù),之后用verify進(jìn)行驗(yàn)證。
比如,verify(bar, times(1)).someMethod(); 來驗(yàn)證bar這個(gè)對(duì)象,調(diào)用了1次someMethod方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容