电竞比分网-中国电竞赛事及体育赛事平台

分享

Mockito使用

 instl 2015-03-19

 最近用Mockito寫了好多測(cè)試,之所以選中Mockito,而不是EasyMock,或者JMock,是因?yàn)槲铱戳斯俜降膶?duì)比文檔:Mockito對(duì)比EasyMock,從文檔中就可以看出來,Mockito的語法很自然,而EashMock之類的什么record,play模型顯得有點(diǎn)多余。Mockito的所有功能都在Mockito這個(gè)類中,里面的函數(shù)按功能可分為幾類:
1. 參數(shù)匹配 — 就是Matchers里的那些any開頭的函數(shù)
2. Mock
3. 打樁(stub)功能 — 就是那些do什么開頭的函數(shù)
4. 驗(yàn)證模型, 包括atLeast,atLeastOnce,atMost,only,times等。

大多數(shù)函數(shù)都很直觀,看名字就能知道它的功能,下面是一些稍微復(fù)雜的用法:

1。 如何匹配變長參數(shù)?

public interface OrderDao
{
    public void saveOrders(Order ...order);
}
public class OrderServiceImpl 
{
    OrderDao orderDao;
    
    public void addOrders(Order ...o)
    {
        orderDao.saveOrders(o);
    }
}

變長參數(shù)其實(shí)就是一個(gè)參數(shù)數(shù)組,所以可以用any(類[].class)類匹配它,像這樣

public class OrderServiceImplTest
{
    @Test
    public void addOrder()
    {
        OrderDao dao = mock(OrderDao.class);
        OrderServiceImpl orderService = new OrderServiceImpl(dao);
        Order o = new Order(1);
        
        //when(dao.)
        orderService.addOrders(o);
        verify(dao,times(1)).saveOrders(any(Order[].class));
    }
}

Mockito本來有個(gè)anyVararg就是作這個(gè)的,不過我用了發(fā)現(xiàn)不行,有點(diǎn)奇怪。

2. Mock和Spy的區(qū)別
如果你mock了一個(gè)類,那么這個(gè)類的所有的函數(shù)都被Mockito改寫了(如果是沒有返回值的函數(shù),則什么都不作,如果是有返回值,會(huì)返回默認(rèn)值,比如布爾型的話返回false,List的話會(huì)返回一個(gè)空的列表,int的話會(huì)返回0等等),如果你Spy了一個(gè)類,那么所有的函數(shù)都沒有被改變,除了那些被你打過樁的函數(shù)。看例子:

public class TestServiceImpl
{
    public int getOrderCounts()
    {
        return 10;
    }
}
@Test
    public void MockVsSpy()
    {
        TestServiceImpl service = mock(TestServiceImpl.class);
        //輸出0,因?yàn)樵摵瘮?shù)被Mockito改寫了
        System.out.println("Order counts of mock object" + service.getOrderCounts());
        when(service.getOrderCounts()).thenReturn(2);
        //輸出2, 因?yàn)槲覀兘o這個(gè)函數(shù)打了樁
        System.out.println("Order counts of mock object AFTER stubs " + service.getOrderCounts());
        
        service = new TestServiceImpl();
        service = spy(service);
        //輸出10, 因?yàn)镸ockito spy 不會(huì)改寫已有的函數(shù)
        System.out.println("Order counts of spy object" + service.getOrderCounts());
        when(service.getOrderCounts()).thenReturn(2);
        //輸出2, 因?yàn)槲覀兘o這個(gè)函數(shù)打了樁
        System.out.println("Order counts of spy object AFTER stubs " + service.getOrderCounts());
    }

3. 如何寫自定義的參數(shù)匹配器

看下面的例子

public class Account
{
    private String    name;
    private String    adddress;

    public Account(String name, String address)
    {
        this.name = name;
        this.adddress = address;
    }
    ...get/set 函數(shù)
}
public interface AccountDao
{
    public void addAccount(Account a);
}

public class AccountServiceImpl
{
    AccountDao dao;
    
    public AccountServiceImpl(AccountDao dao)
    {
        this.dao = dao;
    }
    
    public void addAccount(String name, String address)
    {
        dao.addAccount(new Account(name, address));
    }
}


public class AccountServiceImplTest
{
    @Test
    public void addAccount()
    {
        AccountDao dao = mock(AccountDao.class);
        AccountServiceImpl service = new AccountServiceImpl(dao);
        
        service.addAccount("obama", "white house");
        
        verify(dao).addAccount(new Account("obama", "white house"));
    }
}

上面的例子會(huì)失敗,因?yàn)镸ockito在做參數(shù)匹配時(shí)是根據(jù)equals函數(shù)的結(jié)果來判斷兩個(gè)參數(shù)是不是一樣的。而我們的Account類并沒有對(duì)equals作特殊的實(shí)現(xiàn),所以會(huì)失敗。修正的方法有三個(gè),一個(gè)是改寫Account類的equals函數(shù)。一個(gè)是用Mockito的反射相等匹配,就是把最后一句改成

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多