1. 程式人生 > >Mockito入門、例項及完整介紹

Mockito入門、例項及完整介紹

回到官網:http://mockito.org/,開啟documentation可以看到原文。

強烈建議不熟悉Mockito的同學先看看我寫的Mockito(一)入門篇和(二)例項篇之後再來看這篇文章。

因為只有看了前兩篇文章才明白mockito的本質以及該如何使用它。

下面是按原文 翻譯+註釋 的對Mockito全部功能的介紹。

1, 使用mockito驗證行為。

//首先要importMockito.

import static org.mockito.Mockito.*;

//mock creation

List mockedList = mock(List.class);

//using mock object

mockedList.add("one");

mockedList.clear();

//驗證add方法是否在前面被呼叫了一次,且引數為“one”。clear方法同樣。

verify(mockedList).add("one");

verify(mockedList).clear();

//下面的驗證會失敗。因為沒有呼叫過add("two")。

verify(mockedList).add("two");

原文中的一句話很重要:Once created, mock will remember all interactions.所以mockito知道前面是否呼叫過某方法。

2, 使方法呼叫返回期望的值。也被稱為stubbing

//You can mock concrete classes, not only interfaces

LinkedList mockedList = mock(LinkedList.class);

//stubbing。當get(0)被呼叫時,返回"first". 方法get(1)被呼叫時,拋異常。

when(mockedList.get(0)).thenReturn("first");

when(mockedList.get(1)).thenThrow(new RuntimeException());

//following prints "first"

System.out.println(mockedList.get(0));

//following throws runtime exception

System.out.println(mockedList.get(1));

//following prints "null" because get(999) was not stubbed

System.out.println(mockedList.get(999));

預設情況下,對於所有有返回值且沒有stub過的方法,mockito會返回相應的預設值。

對於內建型別會返回預設值,如int會返回0,布林值返回false。對於其他type會返回null。

這裡一個重要概念就是: mock物件會覆蓋整個被mock的物件,因此沒有stub的方法只能返回預設值。

//重複stub兩次,則以第二次為準。如下將返回"second":

when(mockedList.get(0)).thenReturn("first");

when(mockedList.get(0)).thenReturn("second");

//如果是下面這種形式,則表示第一次呼叫時返回“first”,第二次呼叫時返回“second”。可以寫n多個。

when(mockedList.get(0)).thenReturn("first").thenReturn("second");

但是,如果實際呼叫的次數超過了stub過的次數,則會一直返回最後一次stub的值。

如上例,第三次呼叫get(0)時,則會返回"second".

3, 引數匹配

在上例中如果想實現get(任意整數)時,都返回“element”時,該怎麼做呢?很簡單。

//stubbing 使用了內建的anyint() matcher.

when(mockedList.get(anyInt())).thenReturn("element");

//因此除了anyint()之外,還有其他很多matcher。這裡請參考原文。

//使用了matcher一樣可以驗證被呼叫的次數。

verify(mockedList).get(anyInt());

這裡有一個限制就是,如果在呼叫方法時需要傳入多個引數,其中一個引數使用了argument matcher,那麼所有的引數必須都是matcher。

不可以matcher和實際的引數混著用。

這裡也可以使用custom argument matcher。因為很多時候輸入引數不是build-in 型別,而是我們自己寫的一些類,或特殊物件。

這時要使用argument matcher,就必須訂製特殊的matcher了。

下例是一個特殊的matcher的例項,這個matcher可以匹配任何file物件。

public class SayHiTest {

 @Test
 public void testSayHi() throws Exception {
     File mock = mock(File.class); //首先mock File類。
     //注意new IsAnyFiles()並不是一個matcher,需要呼叫argThat(new IsAnyFiles()))才返回一個matcher。

     //下句中stub:當呼叫renameTo方法時,返回false。該方法引數可以是任意file物件。

     when(mock.renameTo(argThat(new IsAnyFiles()))).thenReturn(false); 
     mock.renameTo(new File("test")); 

     //下句verify renameTo方法被呼叫了一次,同時輸入引數是任意file。
     verify(mock).renameTo(argThat(new IsAnyFiles()));
 }
}
 
class IsAnyFiles extends ArgumentMatcher<File> {
    public boolean matches(Object file) {
        return file.getClass() == File.class;
    }
 }

另外一個引數匹配的例子:

            class IsSOAPMessage extends ArgumentMatcher<SOAPMessage> {

                        public boolean matches(Object soapMessage) {

                                    return (soapMessage instanceof SOAPMessage) || soapMessage==null;

                        }

            }

//上面的macther不僅可以匹配任意的SOAPMessage物件,如果輸入引數為空也可以匹配上。

這裡說一下我犯過的一個錯誤。

我在做引數匹配的時候,沒有考慮到輸入引數為空的情況,導致matcher匹配不上,進而stub的行為無法生效。

其實在發現mock物件沒有想自己想象的方式工作時,最好的方法就是debug進去,首先要先確定mock物件是不是真的傳遞進去了。然後再一步步的debug。

通常遇到的兩種情況就是1,mock物件沒有傳遞進去。2,引數沒有匹配上。

4, 驗證方法被呼叫了特定次數/至少x次/最多x次/從未被呼叫

//是否add("twice")被呼叫了兩次。

 verify(mockedList, times(2)).add("twice");

//驗證add("twice")被呼叫了至少一次。以及其他。

verify(mockedList, atLeastOnce()).add("twice");

verify(mockedList, atLeast(2)).add("twice");

verify(mockedList, atMost(5)).add("twice");

verify(mockedList, never()).add("twice");

5, 呼叫方法時丟擲異常

doThrow(new RuntimeException()).when(mockedList).clear();

後面還會再介紹幾個類似的方法,例如doReturn()。

6, 驗證順序

//下面的程式碼驗證firstMock先被呼叫,secondMock後被呼叫。

inOrder.verify(firstMock).add("was called first");

inOrder.verify(secondMock).add("was called second");

7, 驗證mock之間沒有相互作用6,7都不是很明白實際意義是什麼。

8, 找到冗餘的呼叫

用never()就可以實現,不多說

9, 使用@mock 定義mock。


之前都是使用mock()來模擬一個物件。用@mock是一個shorthand。

public class ArticleManagerTest {

@Mock private ArticleCalculator calculator;

@Mock private ArticleDatabase database;

@Mock private UserProvider userProvider;

private ArticleManager manager;

之後再繼續介紹mockito複雜一點的功能。

相關推薦

Mockito入門例項完整介紹

回到官網:http://mockito.org/,開啟documentation可以看到原文。 強烈建議不熟悉Mockito的同學先看看我寫的Mockito(一)入門篇和(二)例項篇之後再來看這篇文章。 因為只有看了前兩篇文章才明白mockito的本質以及該如何使用它。 下面是按原文 翻譯+註釋 的對

微信小程式入門從這裡出發(登入註冊開發工具檔案結構介紹

![](http://image.ideal-20.cn/weixin-mini/19-01-01-000.png) # (一) 準備工作 ## (1) 登入註冊 - 註冊賬號:這就不談了,只需要注意使用一個全新的郵箱,別之前註冊過公眾號小程式等就可以了 - `https://mp.weixin.q

小程式開發之元件事件處理函式routesetData介紹

元件事件處理函式 Page 中還可以定義元件事件處理函式。在渲染層的元件中加入事件繫結,當事件被觸發時,就會執行 Page 中定義的事件處理函式。 .wxml <view bindtap="viewTap">click me</view> .js

wait()waitpid()waitid()介紹

這三個函式的原型如下:        #include <sys/types.h>        #include <sys/wait.h>        pid_t wait(int *status);        pid_t waitpi

Scala之ListBufferArrayBufferQueueStack介紹

1、程式碼 package com.yy.base import scala.collection.immutable.Queue object BufferQueueAndStackTest extends App { //ListBuffer import

FFmpeg下載安裝內容介紹

FFmpeg是什麼呢?A complete, cross-platform solution to record, convert and stream audio and video.一個完全的,跨平臺的記錄,轉換音視訊流的解決方案。官網地址:http://ffmpeg.o

Spark SQL 1.3.0 DataFrame介紹使用提供了些完整的資料寫入

問題導讀1.DataFrame是什麼?2.如何建立DataFrame?3.如何將普通RDD轉變為DataFrame?4.如何使用DataFrame?5.在1.3.0中,提供了哪些完整的資料寫入支援API? 自2013年3月面世以來,Spark SQL已經成為除Spark C

Cgroup介紹應用例項原理描述

Cgroup介紹 CGroup 是 Control Groups 的縮寫,是 Linux 核心提供的一種可以限制、記錄、隔離程序組 (process groups) 所使用的物力資源 (如 cpu memory i/o 等等) 的機制。2007 年進入 Lin

CGroup 介紹應用例項原理描述

在 IBM Bluemix 雲平臺上開發並部署您的下一個應用。 CGroup 介紹 CGroup 是 Control Groups 的縮寫,是 Linux 核心提供的一種可以限制、記錄、隔離程序組 (process groups) 所使用的物力資源 (如 cpu memory i/o 等等) 的

Randoop介紹安裝環境變量配置

you 套件 文件路徑 令行 sts dt.jar 開發 通知 一個 大體來說,開發人員開發源程序,測試人員找bug,中間人產品經理。 黑盒測試:(不看代碼) 白盒測試:     1、基於覆蓋:語句、分支(if、for、真假)、方法     結構:順序、分支(T or F,

沫沫金原創提供:完整的根據身份證獲取省份性別年齡生日頁面驗證

數字 部分 ast script cit key oot test log 概述: 身份證的校驗,識別,分離,處處可見。最近H5移動端的項目就需要掃碼獲取身份證,根據身份證自動識別省份、性別、年齡、生日信息。這裏分享完善版,希望大家喜歡。 環境: 依賴jQuery、Boot

linux入門基礎知識簡單命令介紹

linux基礎linux入門基礎知識介紹1、計算機硬件組成介紹計算機主要由cpu(運算器、控制器),內存,I/O,外部存儲等構成。 cpu主要是用來對二進制數據進行運算操作,它從內存中取出數據,然後進行相應的運算操作。不能從硬盤中直接取數據。 內存從外部存儲中取出數據供cpu運存。內存的最小單位是

微信小程序 WXMLWXSS 和JS介紹詳解

名單 獲取 hang href 直接 last 1.2 data sub 前幾天折騰了下。然後列出一些實驗結果,供大家參考。 百牛信息技術bainiu.ltd整理發布於博客園 0. 使用開發工具模擬的和真機差異還是比較大的。也建議大家還是真機調試比較靠譜。 1. WXML(

python語法基礎ifwhilefor等語句介紹

python代碼註釋:單行註釋以#開頭,右邊當做註釋,一般註意下一行內容,方便維護記憶。多行註釋以一對三單引號或一對三雙引號 python2不管中文是代碼還是註釋都會報錯,而python就不會,解決辦法如下:#coding=utf-8或#-*- coding:utf-8 -*-(python推薦的) 雖然也是

mysql優化-優化入門之MySQL的優化介紹執行步驟

個人 步驟 應該 是不是 查詢優化 重點 開啟 使用 返回 優化到底優化什麽? 優化,一直是面試最常問的一個問題。因為從優化的角度,優化的思路,完全可以看出一個人的技術積累。那麽,關於系統優化,假設這麽個場景,用戶反映系統太卡(其實就是高並發),那麽我們怎麽優化?

ziptar工具的介紹用法

centos 7 zip tar 6.5 zip壓縮工具6.6 tar打包6.7 打包並壓縮6.5 zip壓縮工具直接壓縮 格式 zip 1.txt.zip 1.txt //可以看到zip需要先命名文件[root@centos7 tmp]# ls -lh 1.txt 查看文件大小 -rw-r

bash腳本之函數簡單介紹應用函數的簡單遞歸調用

bash腳本bash腳本編程--函數 在bash中,函數是由命令和語句結構構成的能夠實現特定功能的集合; 為什麽要在bash中引入函數? 在bash腳本編寫過程中有可能會出現重復且不做任何改變的代碼內容,如果這類內容全靠原始代碼書寫的話不易於排錯和優化;因此我們可以選擇將此類代碼封裝在函數中,在適當的場景中可

linux的php-fpm的pool慢執行日誌進程管理open_basedir介紹

effect 記得 errors 根據 rest time -a 分享 mit php-fpm的pool Nignx可以配置多個虛擬主機,php-fpm同樣也支持配置多個pool,每一個pool可以監聽一個端口,也可以監聽一個socket。 php-fpm配置說明:

Linux發行版介紹Linux系統基礎使用入門Linux命令幫助Linux基礎命令

系統運維 Linux 計算機打的基礎知識:CPU(運算器、控制器)、memory、I/O(輸入設備、輸出設備) 程序運行模式: 用戶空間:user space,us (可執行普通指令) 內核空間:system space (可執行特權指令) POS:Postable Operatin

Ansible的安裝配置常用模塊介紹

touch cbc tor ext num using remove face 附加 Ansible的安裝、配置及常用模塊介紹 ansible安裝方式 1、 ansible安裝常用兩種方式,yum安裝和pip程序安裝 這裏提供二種安裝方式,任選一種即可: 1、使用yum