1. 程式人生 > >Java mocking 單元測試框架介紹

Java mocking 單元測試框架介紹

我需要在資料庫裡插入一些資料,基於這些真實的資料我才可以進行單元測試,而且每次都需要重複準備指令碼,還要考慮資料的清理。
我需要啟動一個Tomcat,然後通過Http Client傳送請求,然後觀察資料,才可以進行測試。
我需要啟動Dubbo服務的提供者,因為我的類裡依賴的這個服務,否則我的類沒辦法正常執行。
我需要依賴第三方的一個介面,因為我這個類是用來發送簡訊的,這樣我才能驗證我的簡訊傳送時正常的。往往第三方都沒有測試環境,即使有的話也不穩定,導致我不能經常進行持續整合的測試。
……
我們主要的面臨的問題是,由於所依賴的元件不容易構造或者不容易獲取,所以導致我們不容易寫出單元測試,甚至由於覺得麻煩索性不寫單元測試(悲傷),如:
HttpServletRequest必須在web容器中才能構造出來;
Dubbo服務必須有服務提供者;
依賴第三方的一個介面,如簡訊,支付等。http介面, webservice介面等;
JDBC中的ResultSet物件;

Mock測試就是在測試過程中,對於某些不容易構造或者不容易獲取比較複雜的物件,用一個虛擬的物件來建立以便測試的測試方法。
Mock最大的功能是幫你把單元測試的解耦,如果你的程式碼對另一個類或者介面有依賴,它能夠幫你模擬這些依賴,並幫你驗證所呼叫的依賴的行為。

Mcokito框架使用:

驗證行為

import static org.mockito.Mockito.*;

public void once_created_mock_will_remember_all_interactions() {
    List<String> mockedList = mock(List.class
); mockedList.add("one"); mockedList.clear(); //驗證呼叫了add方法,並且引數為one verify(mockedList).add("one"); verify(mockedList).clear(); verify(mockedList).add("two"); }

打樁–>Stubbing

public void stubbing() {
    LinkedList mockedList = mock(LinkedList.class);

    when(mockedList.get
(0)).thenReturn("first"); when(mockedList.get(0)).thenReturn("second"); System.out.println(mockedList.get(0)); //mock物件會覆蓋整個被mock的物件,因此沒有stub的方法只能返回預設值。 System.out.println(mockedList.get(999)); when(mockedList.get(1)).thenThrow(new RuntimeException()); System.out.println(mockedList.get(1)); }

如果方法返回值沒有stub過,mockito會返回相應的預設值。如int會返回0,布林值返回false。對於其他型別會返回null。重複stub兩次,則以第二次為準。

引數匹配器

public void argument_matcher() {
    LinkedList mockedList = mock(LinkedList.class);

    //設定無論獲取任何位置的值,都返回固定的一個fixed-element
    when(mockedList.get(anyInt())).thenReturn("fixed-element");

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

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

    //自定義引數匹配器
    when(mockedList.contains(argThat(isValid()))).thenReturn(true);

    System.out.println(mockedList.contains("custom-matcher"));

    System.out.println(mockedList.contains("custom-matcher2"));
}

順序呼叫

public void verify_invoke_in_order() {

    List singleMock = mock(List.class);

    singleMock.add("was added first");
    singleMock.add("was added second");

    InOrder inOrder = inOrder(singleMock);

    inOrder.verify(singleMock).add("was added first");
    inOrder.verify(singleMock).add("was added second");
}

註解的使用

@mock:需要被Mock的物件,mock物件的方法不會再被真實呼叫,如果需要呼叫需要使用stub(打樁);
@InjectMocks: 需要將Mock物件注入的物件;
@Captor:(引數捕獲器)捕獲方法引數進行驗證;

@mock與@InjectMocks使用如下:
這裡寫圖片描述
這裡寫圖片描述

現在假設在service層有如下程式碼需要測試:

public boolean isEmployee(String phoneNumber) {
        if (StringUtils.isEmpty(phoneNumber)) {
            return false;
        }
        return userRepository.findByPhoneNumber(phoneNumber).isPresent();
    }

測試程式碼:

 @Mock
 private userRepository userRepository;
 @InjectMocks
 private userServiceImpl userServiceImpl;

 @Test
 public void testMock() {
      User user = new User();
      stub(userRepository
                .findByPhoneNumber(anyString()))
                .toReturn(Optional.of(user));
      userServiceImpl.isEmployee("110");
      verify(userRepository,times(1))
     .findByPhoneNumber("110");//findByPhoneNumber方法被呼叫一次
    }

如上可以正常測試。但是將最後一行findByPhoneNumber(“110”)號碼改成119酒會報錯,如下:
這裡寫圖片描述

單元測試三步驟:設定測試資料,設定預期結果,驗證結果,三步通過,測試通過。

@Captor使用如下:
ArgumentCaptor的Api
argument.capture() 捕獲方法引數
argument.getValue() 獲取方法引數值,如果方法進行了多次呼叫,它將返回最後一個引數值
argument.getAllValues() 方法進行多次呼叫後,返回多個引數值
程式碼案例:

@Captor
private ArgumentCaptor<Money> moneyCaptor;
@Captor
private ArgumentCaptor<User> userCaptor;


verify(userMoneyService, times(1)).updateStatus( userCaptor.capture(),moneyCaptor.capture());//獲取引數
assertThat(userCaptor.getValue().getRole(), is("Admin");//驗證引數
assertThat(moneyCaptor.getValue(), is("15rmb");

//updateStatus方法如下
public void updateStatus(User user,Money money){
    執行方法……
}

相關推薦

Java mocking 單元測試框架介紹

我需要在資料庫裡插入一些資料,基於這些真實的資料我才可以進行單元測試,而且每次都需要重複準備指令碼,還要考慮資料的清理。 我需要啟動一個Tomcat,然後通過Http Client傳送請求,然後觀察資料,才可以進行測試。 我需要啟動Dubbo服務的提供者,因

TestNg JAVA 自動化單元測試框架Demo

環境準備 既然是java 的自動化單元測試框架,就必須要有java的環境了,這裡使用的編輯器是Eclipse,已經安裝過TestNg 外掛,如果環境準備好就可以開始了 程式碼例項 程式碼結構

Java JUnit 單元測試框架

JUnit是一個Java語言的單元測試框架。 Junit 測試也是程式設計師測試,即所謂的白盒測試 如使用eclipse 開發,不用新增jar包,eclipse內部已經集成了,我們只需要引入即可使用。 1.新增方法,【專案】上右擊,選擇Build Path ,進入 2 .

Python+Selenium框架設計篇之2-簡單介紹unittest單元測試框架

       前面文章已經簡單介紹了一些關於自動化測試框架的介紹,知道了什麼是自動化測試框架,主要有哪些特點,基本組成部分等。在繼續介紹框架設計之前,我們先來學習一個工具,叫unittest。    

JavaScript單元測試框架JsUnit基本介紹和使用

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title> New Document </title> <meta nam

詳解介紹JUnit單元測試框架(完整版)

(一)JUnit介紹 目錄 2.例子 例子 例子 1.什麼是單元測試? 單元測試負責對最小的軟體設計單元(模組)進行驗證,根據軟體設計文件中

Mockito java單元測試框架使用

Mock 測試是單元測試的重要方法之一。本文介紹了基於 Java 語言的 Mock 測試框架 -- Mockito 的使用。 單元測試的思路就是我們想在不涉及依賴關係的情況下測試程式碼. 這種測試

Java單元測試框架Junit

問題: 1、目前測試存在的問題 2、Junit注意的細節 3、Junit使用規範 4、斷言 5、案例 junit(單元測試框架) 1、目前存在的問題 1、目前的測試方法如果需要測試,

JAVA自動化之Junit單元測試框架詳解

一、JUnit概述&配置 1、Junit是什麼? Junit是一個Java 程式語言的開源測試框架,用於編寫和執行測試。官網 地址:https://junit.org/junit4/ 2、Maven配置 ?xml version="1.0" encoding="UTF-8"?> <pr

JavaScript單元測試框架-Jasmine

calling help without 還原 develop util 也不會 目錄結構 函數調用 轉載自金石開的blog:http://www.cnblogs.com/zhcncn/p/4330112.html Jasmine的開發團隊來自PivotalLabs,他

Java Junit單元測試步驟總結

logs 其他 同時 new 技術 src eclipse test 分享 哎呀,莫名其妙已經半夜12點了。總結的如有錯誤的地方歡迎指正,我的這個方法沒有引入jar,網上有其他引入jar包的方法,不是很懂,也沒有太怎麽看。 關鍵的一些基本規則: 下面我們來看Eclipse

TestNG詳解(單元測試框架

參數 http () 彈出 內容 name led 大小 2.4 一、TestNG的優點   1.1 漂亮的HTML格式測試報告   1.2 支持並發測試   1.3 參數化測試更簡單   1.4 支持輸出日誌   1.5 支持更多功能的註解 二、編寫TestNG測試

《selenium2 python 自動化測試實戰》(21)——unittest單元測試框架解析

nbsp add pic post 二維碼 mage ron 而且 aaa unittest是展開自動化測試的基礎——這個框架很重要! 我們先自己寫一個測試類: 1、被測試類 Widthget.py: # coding: utf-8class Wi

單元測試框架

文檔 xtu 函數 ack -h 日誌 去掉 fix 開發 Test庫提供了強有力的單元測試框架(UTF),它為軟件開發的基本領域一單元測試提供了簡單而富有彈性的解決方案,可以滿足開發人員從高到低的各種需求,它的優點包括易於理解,任何人都可以很容易地構建單元測試模塊提供測試

【轉】nose-parameterized是Python單元測試框架實現參數化的擴展

col ever sel mage 多線程 stc nbsp zed testng 原文地址: http://www.cnblogs.com/fnng/p/6580636.html   相對而言,Python下面單元測試框架要弱上少,尤其是Python自帶的unittest

Qt高級——QTestLib單元測試框架

QTestLib 單元測試Qt高級——QTestLib單元測試框架 一、QTestLib簡介 1、QTestLib簡介 QTestLib是Qt提供的一種針對基於Qt編寫的程序或庫的單元測試框架。QTestLib提供了單元測試框架的基本功能,並提供了針對GUI測試的擴展功能。 2、QTestLib特性 QTes

selenium2學習:單元測試框架(1)

xtu urn ace pda -- col 開頭 認識 users 1 單元測試框架 1.1 認識單元測試 Unittest提供了全局的main()方法,使用他可以方便地將一個單元測試模塊變成可以直接運行的測試腳本。Main()方法使用testload

selenium2學習:單元測試框架(2)

__init__ module asc 單獨 sci str mos ddt IT 1.4 Discover更多測試用例 discover(start_dir,pattern=‘test*.py‘,top_level_dir=None) 找到指定目錄下所有測試模塊,

OpenStack基礎知識-單元測試工具介紹

單元測試 pen mongod 大量 需要 哪些 sub 導入 使用 針對以前學的內容的一個簡單整理 1、單元測試工具介紹 unittest: 是 Python 的標準庫,提供了最基本的單元測試功能,包括 單元測試運行器(簡稱runner) 和 單元測試框架。項目的單元測試

Python+Selenium學習筆記16 - unittest單元測試框架

-h 測試框架 pytho skip div 一個 res ima 需要 unittest單元測試框架包括 Test Case, Test Suite, Test Runner, Test Fixture Test Cases 組成Test Suite, Test Run