1. 程式人生 > >【翻譯】Java使用Mockito進行Mock測試

【翻譯】Java使用Mockito進行Mock測試

原文地址:http://java.dzone.com/articles/getting-started-mocking-java文章通過一個簡單例項,介紹了使用Mockito建立mock物件來進行單元測試構建。例子淺顯易懂,相信希望瞭解mock的同學會有所收穫。文章的最後附上我實際構建的maven專案,大家有興趣可以自己實際操作下。

我們所有人在編寫單元測試的時候面臨的巨大挑戰是模組對其他元件的依賴。同時花費大量的時間和精力去配置依賴的元件環境是一件出力不討好的事情。使用Mock是一種有效地方式替代其他元件用來繼續我們的單元測試構建過程。

接下來我將會展示一個使用mock技術的例項。這裡我有一個數據訪問層(簡稱DAL),建立一個類,提供應用程式訪問和修改資料庫中資料的基本API。接著我會測試這個DAL例項,但並不真正連線資料庫。使用DAL類的目的是幫助我們隔離應用程式程式碼和資料顯示層。

讓我們通過下面的命令列建立一個java maven 專案。





mvn archetype:generate -DgroupId=info.sanaulla -DartifactId=MockitoDemo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false



上述命令會建立一個名為MockitoDemo 的資料夾以及對應實體類的目錄結構和測試檔案。

請參考下面的例子來建立一個實體類:





package info.sanaulla.models;

import java.util.List;

/**

Model class for the book details. */ public class Book {

private String isbn; private String title; private List authors; private String publication; private Integer yearOfPublication; private Integer numberOfPages; private String image;

public Book(String isbn,

      String title,
      List<String> authors,
      String publication,
      Integer yearOfPublication,
      Integer numberOfPages,
      String image){

this.isbn = isbn;

this.title = title;

this.authors = authors;

this.publication = publication;

this.yearOfPublication = yearOfPublication;

this.numberOfPages = numberOfPages;

this.image = image;

}

public String getIsbn() {

return isbn;

}

public String getTitle() {

return title;

}

public List getAuthors() {

return authors;

}

public String getPublication() {

return publication;

}

public Integer getYearOfPublication() {

return yearOfPublication;

}

public Integer getNumberOfPages() {

return numberOfPages;

}

public String getImage() {

return image;

}

}

用來操作Book類的DAL類如下:





package info.sanaulla.dal;

import info.sanaulla.models.Book;

import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List;

/**

API layer for persisting and retrieving the Book objects. */ public class BookDAL {

private static BookDAL bookDAL = new BookDAL();

public List getAllBooks(){ return Collections.EMPTY_LIST; }

public Book getBook(String isbn){ return null; }

public String addBook(Book book){ return book.getIsbn(); }

public String updateBook(Book book){ return book.getIsbn(); }

public static BookDAL getInstance(){ return bookDAL; } }

DAL 層現在並沒有實際的功能,我將嘗試用測試驅動開發的方式來構建(TDD)。我們並不關心,DAL層是通過實體關係對映來進行資料通訊還是通過其他資料庫API來實現上面的操作。

資料驅動的資料訪問層

有很多單元測試框架和mock框架,這裡我選擇Junit單元測試框架和moke框架Mockito。我們需要在pom.xml配置檔案中更新對他們的依賴。

   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 <a href="http://maven.apache.org/maven-v4_0_0.xsd">http://maven.apache.org/maven-v4_0_0.xsd"</a>>
  <modelVersion>4.0.0</modelVersion>
  <groupId>info.sanaulla</groupId>
  <artifactId>MockitoDemo</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>MockitoDemo</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!-- Dependency for JUnit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    <!-- Dependency for Mockito -->
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.9.5</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

現在我們編寫BookDAL的單元測試類。通過單元測試,我們可以在BookDAL中注入mock物件進行單元測試而不用依賴其他資料來源。

首先建立一個空的測試類,程式碼如下:





public class BookDALTest {



public void setUp() throws Exception {

}

public void testGetAllBooks() throws Exception {

}

public void testGetBook() throws Exception {

}

public void testAddBook() throws Exception {

}

public void testUpdateBook() throws Exception {

} }

下面的程式碼中,我們在setUp方法中通過mock方式注入BookDAL物件





public class BookDALTest {

private static BookDAL mockedBookDAL; private static Book book1; private static Book book2;

@BeforeClass public static void setUp(){

//Create mock object of BookDAL
mockedBookDAL = mock(BookDAL.class);

//Create few instances of Book class.
book1 = new Book("8131721019","Compilers Principles",
        Arrays.asList("D. Jeffrey Ulman","Ravi Sethi", "Alfred V. Aho", "Monica S. Lam"),
        "Pearson Education Singapore Pte Ltd", 2008,1009,"BOOK_IMAGE");

book2 = new Book("9788183331630","Let Us C 13th Edition",
        Arrays.asList("Yashavant Kanetkar"),"BPB PUBLICATIONS", 2012,675,"BOOK_IMAGE");

//Stubbing the methods of mocked BookDAL with mocked data. 
when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2));
when(mockedBookDAL.getBook("8131721019")).thenReturn(book1);
when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn());
when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn());

}

public void testGetAllBooks() throws Exception {}

public void testGetBook() throws Exception {}

public void testAddBook() throws Exception {}

public void testUpdateBook() throws Exception {}

}

在setUp方法中我通過下面這種方式

1.建立BookDAL例項:





BookDAL mockedBookDAL = mock(BookDAL.class);



2.Mokito API中DAL的mock物件,使用when方法接收呼叫mock物件的方法返回值引數。





//When getAllBooks() is invoked then return the given data and so on for the other methods.



when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2));



when(mockedBookDAL.getBook(“8131721019”)).thenReturn(book1);



when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn());



when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn());



實現其他的已經宣告的測試方法:





package info.sanaulla.dal;

import info.sanaulla.models.Book; import org.junit.BeforeClass; import org.junit.Test;

import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when;

import java.util.Arrays; import java.util.List;

public class BookDALTest {

private static BookDAL mockedBookDAL; private static Book book1; private static Book book2;

@BeforeClass public static void setUp(){

mockedBookDAL = mock(BookDAL.class);
book1 = new Book("8131721019","Compilers Principles",
        Arrays.asList("D. Jeffrey Ulman","Ravi Sethi", "Alfred V. Aho", "Monica S. Lam"),
        "Pearson Education Singapore Pte Ltd", 2008,1009,"BOOK_IMAGE");

book2 = new Book("9788183331630","Let Us C 13th Edition",
        Arrays.asList("Yashavant Kanetkar"),"BPB PUBLICATIONS", 2012,675,"BOOK_IMAGE");

when(mockedBookDAL.getAllBooks()).thenReturn(Arrays.asList(book1, book2));
when(mockedBookDAL.getBook("8131721019")).thenReturn(book1);
when(mockedBookDAL.addBook(book1)).thenReturn(book1.getIsbn());

when(mockedBookDAL.updateBook(book1)).thenReturn(book1.getIsbn());

}

@Test

public void testGetAllBooks() throws Exception {

List<Book> allBooks = mockedBookDAL.getAllBooks();
assertEquals(2, allBooks.size());
Book myBook = allBooks.get(0);
assertEquals("8131721019", myBook.getIsbn());
assertEquals("Compilers Principles", myBook.getTitle());
assertEquals(4, myBook.getAuthors().size());
assertEquals((Integer)2008, myBook.getYearOfPublication());
assertEquals((Integer) 1009, myBook.getNumberOfPages());
assertEquals("Pearson Education Singapore Pte Ltd", myBook.getPublication());
assertEquals("BOOK_IMAGE", myBook.getImage());

}

@Test

public void testGetBook(){

String isbn = "8131721019";
Book myBook = mockedBookDAL.getBook(isbn);

assertNotNull(myBook);
assertEquals(isbn, myBook.getIsbn());
assertEquals("Compilers Principles", myBook.getTitle());
assertEquals(4, myBook.getAuthors().size());
assertEquals("Pearson Education Singapore Pte Ltd", myBook.getPublication());
assertEquals((Integer)2008, myBook.getYearOfPublication());
assertEquals((Integer)1009, myBook.getNumberOfPages());

}

@Test

public void testAddBook(){

String isbn = mockedBookDAL.addBook(book1);
assertNotNull(isbn);
assertEquals(book1.getIsbn(), isbn);

}

@Test

public void testUpdateBook(){

String isbn = mockedBookDAL.updateBook(book1);
assertNotNull(isbn);
assertEquals(book1.getIsbn(), isbn);

}

}

然後我們通過maven的命令航方式:mvn test運行當前的專案。控制檯輸出如下:





-——————————————————



T E S T S



-——————————————————



Running info.sanaulla.AppTest



Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.029 sec



Running info.sanaulla.dal.BookDALTest



Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.209 sec

Results :

Tests run: 5, Failures: 0, Errors: 0, Skipped: 0

現在我們就實現了即使不配置資料來源方式,而使用mock物件來測試DAL類。

例項程式碼


相關推薦

翻譯Java使用Mockito進行Mock測試

原文地址:http://java.dzone.com/articles/getting-started-mocking-java文章通過一個簡單例項,介紹了使用Mockito建立mock物件來進行單元測試構建。例子淺顯易懂,相信希望瞭解mock的同學會有所收穫。文章的最後附

關於java 單元測試Junit4和Mock的一些總結

原文出處請點選這裡 1. 單元測試的必要性 最近專案有在寫java程式碼的單元測試,然後在思考一個問題,為什麼要寫單元測試??單元測試寫了有什麼用??百度了一圈,如下: 軟體質量最簡單、最有效的保證; 是目的碼最清晰、最有效的文件;

翻譯藉助 NeoCPU 在 CPU 上進行 CNN 模型推理優化

  本文翻譯自 Yizhi Liu, Yao Wang, Ruofei Yu.. 的  "Optimizing CNN Model Inference on CPUs" 原文連結: https://arxiv.org/abs/1809.02697 翻譯:co

Visual Studio單元測試小應用-測執行時間

line Language cat parse esc net 技術分享 javascrip huang 【轉】Visual Studio單元測試小應用-測執行時間 Visual Studio的單元測試會記錄每一個測試的執行時間,如果有幾個Method要測效能,以前我會用

翻譯 View Frustum Culling --1 View Frustum’s Shape

near com 矩形區域 狀態 翻譯 cnblogs 位置 移動 距離 這是一些列來自lighthouse3d的視錐體裁剪教程。旨在學習總結,及便於查閱。 1、視錐體的形狀 在OpenGL中,透視投影是由兩個函數定義的gluPerspective和gluLookAt

翻譯關於vertical-align所有你需要知道的

增加 大寫 內聯 簡單 -s 列表 fin 技術分享 解決方案 本文是翻譯過來的,如果有不對的地方還請指教~,原文鏈接:Vertical-Align: All You Need To Know 前面一些說明,可以略過不看吧 我經常需要對元素進行垂直方向上的布局。 CSS提供

翻譯ASP.NET Core 文檔目錄

www asp nbsp .com col actions size 組件 ons 簡介 入門 創建一個Web應用程序 創建一個Web API 教程 基礎 MVC Razor Pages Razor 語法 Model 綁定

GTD190018:翻譯The Case Against Civilization

sed trait intervals cycle variety enter method nor get https://www.newyorker.com/magazine/2017/09/18/the-case-against-civilization

學習Python進行數據提取的方法總結轉載

多個 pandas flow cells nump 特定 blue 和數 index 鏈接:http://www.jb51.net/article/90946.htm 數據提取是分析師日常工作中經常遇到的需求。如某個用戶的貸款金額,某個月或季度的利息總收入,某個特定時間段的

翻譯‘BadRabbit’ Ransomware Burrows Into Russia, Ukraine

ati exe rar product ner qcow dns query rep stream 【來源】 ‘BadRabbit’ Ransomware Burrows Into Russia, Ukraine By Raj Samani and Christiaan B

翻譯在GitHub上通過星級評估排名前10的最受歡迎的開源Delphi項目

href ref -s 編程 強烈 使用 系統 ioc 進行 GitHub上有相當多的Delphi開源項目可以為你節省一些時間。我在GitHub上搜索了Delphi,然後按最主要的項目進行排序,並列出了前十名單。這裏有一些非常好的東西,包括Awesome Delphi(這是

vuenpm run mock & npm run dev 無法同時運行的解決

1-1 test 搭建 cnpm 無法 cnp 分享圖片 http 有用 【關於系統,沒註明的都是windows系統,若以後用的是mac系統則會另外備註】 當項目數據是通過mock搭建而成(參照:【vue】本地開發mock數據支持)時,運行mock服務器和項目的命令 就參照

翻譯《向“彈跳球”演示程序添加新功能》 in MDN

dev tps sts color htm html nes obj doc 文章地址: https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Objects/%E5%90%91%E2%80%9C%E5%BC%B

NodejsBrowsersync同步瀏覽器測試

配置 pan sync itl 環境變量 html rsync blog npm 說明文檔:http://www.browsersync.cn/docs/ 安裝命令: ①全局安裝 npm install -g browser-sync ②局部/本地安裝 npm in

翻譯- EffectiveAkka-第二章(一)

未來 接口 ask success 就是 -m des exec uri Actor使用模式   現在我們已經了解了可以創建的actor系統的不同類型,那麽我們在編寫基於actor的應用程序時,可以采用什麽樣的使用模式,以便避免出現常見錯誤呢? 下面就讓我們看看其中使用模式

201803112018北京集訓測試賽(二)

char 開始 n) source 數組 區間 但是 多次 pan Problem A: 遊戲 題解&反思 模型轉化挺簡單的,但是轉化成“查詢區間內是否有若幹個數組成的集合xor和為0”問題的時候,突然發現不會做……最後只打了20暴力真是涼涼。 其實線性基這個東

翻譯Apache Shiro10分鐘教程

做什麽 網頁 cnblogs 讓我 技術 參考手冊 user com 分鐘 本文為翻譯文,原文地址:http://shiro.apache.org/10-minute-tutorial.html 介紹 歡迎來到Apache Shiro的10分鐘教程! 通過這個教程,你會完全

201803182018北京集訓測試賽(六)

sum cnblogs 中間 com phi gpo 但是 分享圖片 problem 菜雞滾回石家莊了233 Problem B: 求和 題解&反思: 好久沒寫反演了真刺激 大力推公式就好咯 \[ \sum_{i=1}^{n}\sum_{j=1}^{i}\sum_

第一次個人作業(代碼測試

win asdf 輸出 做的 div 文字 基礎上 abc 個數 在代碼測試環節,我主要對集中典型以及特殊情況做了測試,結果如下: 文件夾測試 TEST1: 空文件夾測試( √ ) I:\TEST\data 為一個空文件夾,測試程序對空文件夾的處理 命令: WordFrq

翻譯Temporal supersampling and antialiasing

鋸齒 In TE ant bar can add rec always 原文鏈接:https://bartwronski.com/2014/03/15/temporal-supersampling-and-antialiasing/ Aliasing problem鋸齒問題