在JUnit測試中使用Builder模式

這并不是要成為技術含量很高的職位。 這篇文章的目的是為您提供一些指導,以使您的JUnit測試生活更加輕松,使您能夠在幾分鐘內編寫復雜的測試場景,并具有易于閱讀的測試優勢。

單元測試中有兩個主要部分,需要編寫許多引導程序代碼:

  • 設置部分:構建初始狀態需要構建將被饋送到SUT(被測系統)的初始對象
  • 斷言部分:構造輸出對象的所需圖像,并僅對所需數據進行斷言。


為了降低構建用于測試的對象的復雜性,我建議在以下解釋中使用Builder模式:

這是域對象:

public class Employee {private int id;private String name;private Department department;//setters, getters, hashCode, equals, toString methods

此域對象的生成器如下所示:

public class EmployeeBuilder {private Employee employee;public EmployeeBuilder() {employee = new Employee();}public static EmployeeBuilder defaultValues() {return new EmployeeBuilder();}public static EmployeeBuilder clone(Employee toClone) {EmployeeBuilder builder = defaultValues();builder.setId(toClone.getId());builder.setName(toClone.getName());builder.setDepartment(toClone.getDepartment());return builder;}public static EmployeeBuilder random() {EmployeeBuilder builder = defaultValues();builder.setId(getRandomInteger(0, 1000));builder.setName(getRandomString(20));builder.setDepartment(Department.values()[getRandomInteger(0, Department.values().length - 1)]);return builder;}public EmployeeBuilder setId(int id) {employee.setId(id);return this;}public EmployeeBuilder setName(String name) {employee.setName(name);return this;}public EmployeeBuilder setDepartment(Department dept) {employee.setDepartment(dept);return this;}public Employee build() {return employee;}
}

如您所見,我們有一些工廠方法:

public static EmployeeBuilder defaultValues()public static EmployeeBuilder clone(Employee toClone)public static EmployeeBuilder random()

這些方法返回不同的構建器:

  • defaultValues:每個字段的一些硬編碼值(或Java默認值-當前實現)
  • clone:將獲取初始對象中的所有值,并使您可以更改其中一些值
  • random:將為每個字段生成隨機值。 當您有很多字段在測試中不需要時非常有用,但是您需要將它們初始化。 getRandom *方法是在另一個類中靜態定義的。

您可以添加其他方法來根據需要初始化構建器。

此外,構建器還可以處理一些不那么容易構建和更改的對象。 例如,讓我們稍微更改Employee對象,使其不可變:

public class Employee {private final int id;private final String name;private final Department department;...
}

現在,我們失去了按需更改字段的可能性。 但是使用以下形式的構建器,我們可以在構造對象時重新獲得這種可能性:

public class ImmutableEmployeeBuilder {private int id;private String name;private Department department;public ImmutableEmployeeBuilder() {}public static ImmutableEmployeeBuilder defaultValues() {return new ImmutableEmployeeBuilder();}public static ImmutableEmployeeBuilder clone(Employee toClone) {ImmutableEmployeeBuilder builder = defaultValues();builder.setId(toClone.getId());builder.setName(toClone.getName());builder.setDepartment(toClone.getDepartment());return builder;}public static ImmutableEmployeeBuilder random() {ImmutableEmployeeBuilder builder = defaultValues();builder.setId(getRandomInteger(0, 1000));builder.setName(getRandomString(20));builder.setDepartment(Department.values()[getRandomInteger(0, Department.values().length - 1)]);return builder;}public ImmutableEmployeeBuilder setId(int id) {this.id = id;return this;}public ImmutableEmployeeBuilder setName(String name) {this.name = name;return this;}public ImmutableEmployeeBuilder setDepartment(Department dept) {this.department = dept;return this;}public ImmutableEmployee build() {return new ImmutableEmployee(id, name, department);}
}

當我們難以構造對象或需要更改最終字段時,這非常有用。

這是它的最終結果:

沒有建設者:

@Testpublic void changeRoleTestWithoutBuilders() {// building the initial stateEmployee employee = new Employee();employee.setId(1);employee.setDepartment(Department.DEVELOPEMENT);employee.setName("John Johnny");// testing the SUTEmployeeManager employeeManager = new EmployeeManager();employeeManager.changeRole(employee, Department.MANAGEMENT);// building the expectationsEmployee expectedEmployee = new Employee();expectedEmployee.setId(employee.getId());expectedEmployee.setDepartment(Department.MANAGEMENT);expectedEmployee.setName(employee.getName());// assertionsassertThat(employee, is(expectedEmployee));}

與建設者:

@Testpublic void changeRoleTestWithBuilders() {// building the initial stateEmployee employee = EmployeeBuilder.defaultValues().setId(1).setName("John Johnny").setDepartment(Department.DEVELOPEMENT).build();// building the expectationsEmployee expectedEmployee = EmployeeBuilder.clone(employee).setDepartment(Department.MANAGEMENT).build();// testing the SUTEmployeeManager employeeManager = new EmployeeManager();employeeManager.changeRole(employee, Department.MANAGEMENT);// assertionsassertThat(employee, is(expectedEmployee));}

如您所見,測試的大小要小得多,對象的構造也變得更加簡單(如果代碼格式更好,也會更好)。 如果您具有更復雜的域對象(在實際應用程序中,尤其是在遺留代碼中),則差異更大。

玩得開心!

參考:來自Java出現日歷博客的JCG合作伙伴 Stefan Bulzan 在JUnit測試中使用了Builder模式 。

翻譯自: https://www.javacodegeeks.com/2012/12/using-builder-pattern-in-junit-tests.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370171.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370171.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370171.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SQL數據庫中臨時表、臨時變量和WITH AS關鍵詞創建“臨時表”的區別

原文鏈接:https://www.cnblogs.com/zhaowei303/articles/4204805.html SQL數據庫中數據處理時,有時候需要建立臨時表,將查詢后的結果集放到臨時表中,然后在針對這個數據進行操作。 創建“臨時表”(邏輯上的臨時表&…

python 三維繪圖庫_Python第三方庫matplotlib(2D繪圖庫)入門與進階

Matplotlib一 簡介:Matplotlib是一個Python 2D繪圖庫,它可以在各種平臺上以各種硬拷貝格式和交互式環境生成出具有出版品質的圖形。 Matplotlib可用于Python腳本,Python和IPython shell,Jupyter筆記本,Web應用程序服務…

zbb20170626 myeclipse 2017 ci 構建 spring hibernate struts jar

轉載于:https://www.cnblogs.com/super-admin/p/7081209.html

linux處理機調度實驗報告,模擬Linux操作系統下處理機調度實驗報告

在采用多道系統的設計程序中,往往有若干進程同時處于就緒狀態。當就緒狀態進程數大于處理機數時,就必須按照某種策略來決定哪些進程優先占用處理機。本實驗模擬在單處理機情況下處理機調度處理機調度一、實驗目的:1、了解Linux下Emacs編輯器的使用方法,掌…

Java線程:保留的內存分析

本文將為您提供一個教程,使您可以確定活動應用程序Java線程保留Java堆空間的數量和位置。 將提供來自Oracle Weblogic 10.0生產環境的真實案例研究,以使您更好地理解分析過程。 我們還將嘗試證明過多的垃圾回收或Java堆空間的內存占用問題通常不是由真正…

軟件測試白皮書-等價類

設有一個檔案管理系統,要求用戶輸入以年月表示的日期。假設日期限定在1990年1月~2049年12月,并規定日期由6位數字字符組成,前4位表示年,后2位表示月。現用等價類劃分法設計測試用例,來測試程序的"日期檢查功能&qu…

深入css布局 (1) — 盒模型 元素分類

深入css布局(1)—— 盒模型 & 元素分類 “ 在css知識體系中,除了css選擇器,樣式屬性等基礎知識外,css布局相關的知識才是css比較核心和重要的點。今天我們來深入學習一下css布局相關的知識。” 首先來列下大綱 盒模…

批改網禁止粘貼怎么破_教育部對家長批改作業表態了,明令禁止!你怎么看?...

互聯網的發展,的確方便了現代人生活。視頻電話、出去買東西你都不用帶錢帶卡,手機一掃就可以完成支付。很多中小學的家長都會建一個家長群,方便老師和家長的溝通。這個群可以說是家長和學校的橋梁和紐帶,家長們為了支持老師的工作…

電子科大專科c語言作業1,電子科大15春《C語言(專科)》在線作業試卷.docx

電子科大 15 春《 C 語言(專科)》在線作業一、單選題(共20 道試題,共100 分。)1.對于 int*p;inta[];pa;的合法運算 ()a;pa;p; 相當于 a;p; 相當于 a[1];若 p 中的地址為 100 則 p; 運算后,則其值為 100-----------------選擇: C已知 intb; 則…

MapReduce算法–順序反轉

這篇文章是介紹MapReduce算法的系列文章的另一部分,該書在使用MapReduce進行數據密集型文本處理中找到。 先前的文章是Local Aggregation , Local Aggregation PartII和創建共現矩陣 。 這次我們將討論階數反轉模式。 順序反轉模式利用的MapReduce來計算…

xss防御

http://blog.csdn.net/ghsau/article/details/17027893轉載于:https://www.cnblogs.com/jiangjing/p/8076216.html

移動端頁面字體在微信被放大,導致排版錯亂

在開發微信頁面的時候,之前一直沒有測出這個問題。直到某天領導的手機出現了排版錯位的問題,拿著手機質問我的工作態度。 Google了一下發現原來微信調整了字體大小會放大網頁的字體,導致排版混亂。通過設置可以禁止網頁字體被放大&#xff1a…

液壓支架銷軸力學計算分析研究_基于RFID射頻精準定位的智能開采研究與應用...

一、項目背景近年來隨著智能開采技術的不斷發展,裝備和新工藝不斷更新換代,在智能開采中,對采煤機位置的精準定位是能否實現智能開采的關鍵,只有準確無誤地獲取煤機的準確位置,才能實現工作面的智能化開采,進而提高生產…

cf 821E Okabe and El Psy Kongroo(矩陣快速冪)

鏈接:http://codeforces.com/problemset/problem/821/E 分析:由于有邊界而且不同段邊界還不同,直接算是不行的。。k是1e18,dp也不行。。用一個16維的向量表示某一列16個位置可能的種類數,到下一列的轉移矩陣容易得到&a…

您是否能及時編譯?

還記得上次被C開發人員嘲笑的時候嗎? Java如此繁瑣,以至于他們甚至都不會考慮使用這種語言? 在許多方面,這一概念仍然成立。 但是對于典型的用法(在大型企業的骨干中),Java性能絕對可以與許多競…

C語言作業二選擇結構,C語言第二次作業參考答案選擇結構.pdf

1 C 語言第二次作業(選擇結構)參考答案語言第二次作業(選擇結構)參考答案 1、某年如果能被某年如果能被 4 整除整除,,但不能被但不能被 100 整除整除,,或者能被或者能被 400 整除的整除的 年是閏年。判斷從鍵盤輸入的年份是否為閏…

2d物理引擎01

我一直想做一個游戲&#xff0c;但一直感覺自己水平不夠 想了想覺得不去做的話就永遠做不出來 所以有了這個博文 01 我需要一個東西來顯示&#xff0c;很顯然h5中canvas是很好的選擇 <!DOCTYPE html> <html><head><meta charset"utf-8" />&l…

python結課設計力學方面_我對力學教案的評價

這是來自某教學網站的高一物理力學教案&#xff1a;[高一物理教案1.1.1]第一章 力1&#xff0e;1 力一、教學目標1&#xff0e;知識目標⑴知道力是物體對物體的作用&#xff0c;力不能脫離物體而存在&#xff1b;能正確找出受力物體和施力物體。⑵知道力是有方向的量&#xff…

Liferay Model Hints

這篇文章主要介紹如何通過model hint 來修改liferay builder service生成數據庫表中默認字段的長度。 1.什么是Model Hints? 它是對liferay builder service生成的model類的基本提示. 2. 它在什么地方被定義的&#xff1f; portlet-model-hints.xml 3. 文件位置&#xff1f; /…

瀏覽器書簽備份管理

1、火狐瀏覽器備份導出HTML文件&#xff1a; CtrlJ 書簽 - 導入/導出 2、谷歌瀏覽器&#xff1a; 設置中 導入書簽 轉載于:https://www.cnblogs.com/AmbiguousMiao/p/8084721.html