測試抽象類和模板方法模式

摘自Wikipedia,“模板方法定義了算法的程序框架。 子類可以覆蓋一個或多個算法步驟,以允許不同的行為,同時確保仍然遵循總體算法。”

通常,此模式由兩個或多個類組成,一個是提供模板方法(非抽象)的抽象類,該模板方法具有對由一個或多個具體子類實現的抽象方法的調用。

模板抽象類和具體實現通常位于同一項目中,但是根據項目范圍,這些具體對象將被實現到另一個項目中。

在這篇文章中,我們將看到在外部項目上實現具體類時如何測試模板方法模式,或更一般的如何測試抽象類。

讓我們看一個簡單的模板方法模式示例。 考慮一個負責接收整數向量并計算歐幾里得范數的類。 這些整數可以從多個來源接收,并留給每個項目以提供一種獲取它們的方法。

模板類如下所示:

public abstract class AbstractCalculator {public double euclideanNorm() {int[] vector = this.read();int total = 0;for(int element:vector) {total+= (element*element);  }return Math.sqrt(total);}public abstract int[] read();
}

現在,另一個項目可以擴展上一類,并通過提供read()方法的實現來實現抽象計算器。

public class ConsoleCalculator extends AbstractCalculator {public int[] read() {int [] data = new int[0];Scanner scanner = new Scanner(System.in);//data = read requried data from consolereturn data; }}

編寫了具體實現的開發人員將只測試read()方法,他可以“相信”抽象類的開發人員已經測試了非抽象方法。

但是,如果類是抽象的并且需要read()方法的實現,我們將如何在計算方法上編寫單元測試?

第一種方法可能是創建偽造的實現:

public class FakeCalculator extends AbstractCalculator {private int[] data;public FakeCalculator(int[] data) {this.data = data;}public int[] read() {return this.data;}}

這不是一個壞方法,但是有一些缺點:

  • 測試的可讀性較低,讀者應該知道這些假類的存在,并且必須確切地知道他們在做什么。
  • 作為測試作者,您將花費時間來實現偽類,在這種情況下,這很簡單,但是您的項目可能有多個不執行任何抽象類,甚至使用不止一個抽象方法。
  • 偽造類的行為是“硬編碼的”。

更好的方法是使用Mockito僅模擬抽象方法,同時調用非抽象方法的實現。

public class WhenCalculatingEuclideanNorm {@Testpublic void should_calculate_correctly() {AbstractCalculator abstractCalculator = mock(AbstractCalculator.class, Mockito.CALLS_REAL_METHODS);doReturn(new int[]{2,2}).when(abstractCalculator).read();assertThat(abstractCalculator.euclideanNorm(), is(2.8284271247461903));}@Testpublic void should_calculate_correctly_with_negative_values() {AbstractCalculator abstractCalculator = mock(AbstractCalculator.class, Mockito.CALLS_REAL_METHODS);doReturn(new int[]{-2,-2}).when(abstractCalculator).read();assertThat(abstractCalculator.euclideanNorm(), is(2.8284271247461903));}}

Mockito通過調用真實方法簡化了抽象類的測試,并且僅對抽象方法進行了存根處理。 看到這種情況是因為默認情況下我們正在調用真實方法,而不是使用典型的when()then()結構,而是必須使用doReturn模式。

當然,僅當您的項目不包含算法的具體實現,或者您的項目將成為另一個項目的第3方庫的一部分時,才可以使用此方法。 在其他情況下,解決問題的最佳方法是測試實現的類。

下載源代碼

參考:在One Jar to Rulem All博客上測試了我們的JCG合作伙伴 Alex Soto的抽象類(尤其是模板方法模式) 。


翻譯自: https://www.javacodegeeks.com/2012/06/testing-abstract-classes-and-template.html

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

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

相關文章

LoadRunner性能測試結果計數器指標說明

LoadRunner性能測試結果計數器指標說明 轉載2015-09-23 09:57:13標簽:loadrunner計數器針對性能測試結果分析過程中,面對大量的測試數據,反而感覺無從下手分析。今天我們就Windows操作系統計數器中的個別被監控對象進行簡單的說明。 Memory: …

Elasticsearch之需要注意的問題(es和jdk版本)

(1)在使用java代碼操作es集群的時候 要保證本地使用的es的版本和集群上es的版本保持一致。 (2)保證集群中每個節點的JDK版本和es基本配置一致 這個很簡單,不多說。 (3)es集群中jdk版本不一致 …

oracle視圖查詢數據慢,8i查詢DBA_FREE_SPACE視圖極慢的問題

還是那套古老的8.1.7.4,在該系統上檢查表空間使用情況的SQL運行緩慢,其SQL如下:SELECT D.TABLESPACE_NAME,SPACE "SUM_SPACE(M)",SPACE - NVL(FREE_SPACE, 0) "USED_SPACE(M)",ROUND((1 - NVL(FREE_SPACE, 0) / SPACE) * 100, 2) &q…

bzoj 4332:JSOI2012 分零食

描述 這里是歡樂的進香河,這里是歡樂的幼兒園。 今天是2月14日,星期二。在這個特殊的日子里,老師帶著同學們歡樂地跳著,笑著。校長從幼兒園旁邊的小吃店買了大量的零食決定分給同學們。聽到這個消息,所有同學都安安靜靜…

并發–順序線程和原始線程

我不久前參與了一個項目,該項目的報告流程如下: 用戶會要求舉報 報告要求將被翻譯成較小的部分 每個零件的報告將基于零件/節的類型由報告生成器生成 組成報告的各個部分將重新組合成最終報告,并返回給用戶 我的目標是展示如何從錯誤的實…

借貸期末余額 oracle,應交稅費期末余額分別在借貸方表示什么

應交稅費是負債類科目,有時期末余額會在借方,有時會在貸方。因此,小伙伴們在實際的賬務處理工作中,一定要弄清楚兩者的含義。為了幫助大家進行有更進一步的理解,小編再次匯總了應交稅費期末余額分別在借貸方表示什么的…

Android學習——ListView的緩存機制

在使用ListView的時候,需要加載適配器和數據源,這篇文章主要介紹一下ListView的使用以及利用ListView的緩存機制來減少系統的初始化時間。 ListView的使用 ListView和ViewPager很類似,首先在ArrayList中存放數據源,并把它作為Adap…

C#基礎 特殊集合(棧集合、隊列集合、哈希表集合)

一、 棧: Stank,先進先出,一個一個賦值,一個一個取值,按照順序。 .count 取集合內元素的個數 .push 將元素一個一個推入集合 .pop 將元素一個一個彈出集合 .peek 查看集合中的一個元素 .clear 清空集合 Stack stnew Stack…

OSGi環境中的Servlet基本身份驗證

您首先需要獲得對OSGI HTTP Service的引用。 您可以通過聲明性服務來做到這一點。 這篇文章將集中在獲得對HTTP服務的引用之后的步驟。 注意:此職位的完整課程位于此處 通過OSGI HTTP Service注冊Servlet時,它為您提供了提供HTTPContext實現的選項。 htt…

linux夏令時配置文件,Linux夏令時是怎么調整的?

以法國巴黎為例:root121 zoneinfo]# ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime[root121 zoneinfo]# date2015年 10月 13日 星期二 03:45:09 CEST[root121 zoneinfo]# date -RTue, 13 Oct 2015 03:45:31 0200[root121 zoneinfo]# zdump -v /etc/localt…

Kali Linux滲透基礎知識整理(二)漏洞掃描

Kali Linux滲透基礎知識整理系列文章回顧 漏洞掃描 網絡流量NmapHping3NessuswhatwebDirBusterjoomscanWPScan網絡流量 網絡流量就是網絡上傳輸的數據量。 TCP協議 TCP是因特網中的傳輸層協議,使用三次握手協議建立連接。當主動方發出SYN連接請求后,等待…

嵌入式軟件設計第09實驗報告

學號:140201133 姓名:李宇昕 組別:第3組 實驗地點:D19 一、實驗目的: 1.熟悉WWW技術中的SSI(Server Side Include)技術。 2.學會使用SSI技術編寫代碼把當前開發板內…

TeamCity工件:HTTP,Ant,Gradle和Maven

您可以通過幾種方式檢索TeamCity工件? 我說有很多選擇 ! 如果您使用的是Java構建工具,那么可以使用簡單的HTTP請求,Ant Ivy,Gradle和Maven下載和使用TeamCity構建配置生成的二進制文件。 怎么樣? 繼續閱讀…

linux中hadoop命令大全,hadoop常用命令

啟動Hadoop進入HADOOP_HOME目錄。執行sh bin/start-all.sh關閉Hadoop進入HADOOP_HOME目錄。執行sh bin/stop-all.sh1、查看指定目錄下內容hadoop dfs –ls [文件目錄]eg: hadoop dfs –ls /user/wangkai.pt2、打開某個已存在文件hadoop dfs –cat [file_path]eg:hadoop dfs -ca…

Uber從Postgres切換到MySQL

Uber工程師在官方博客上描述了他們為什么要從 Postgres 切換到 MySQL 數據庫。Uber的早期架構是由 Python編寫的后端應用構成,使用了 Postgres 數據庫。但此后,Uber的架構發生了顯著的改變,轉變到了微服務模型和新的數據平臺。以前他們使用 P…

AutoCAD如何方便截圖放到Word文檔,改成白底黑字

將模型視圖切換到布局2即可 比如下圖所示的效果 先回到模型視圖把所有線條顏色都改成白色,然后添加適當的標注(比如要受力分析,則在CAD中繪制箭頭也很方便的),文字說明。然后切換到布局2就OK 可以截圖了。 轉載于:http…

在Hotspot JVM中跟蹤過多的垃圾回收

由于內存泄漏或其他內存問題,經常導致應用程序凍結,僅使垃圾收集器(GC)進程運行失敗,試圖釋放一些空間。 直到看門狗(或沮喪的管理員)重新啟動應用程序并且問題從未解決之前,這種情況…

linux 網絡在線升級,linux在線升級

//前提信息:1.系統分區信息SPI-Flash:[0] 0x000000000000-0x000000020000 : "SPL,128KB"[1] 0x000000020000-0x0000000e0000 : "U-Boot,768KB"[2] 0x0000000e0000-0x000000100000 : "U-Boot Env,128KB"[3] 0x000000100000-0x00000020…

XML反序列化出錯,XML 文檔(2, 2)中有錯誤

XML轉換為實體類的錯誤處理方案 一.錯誤描述&#xff1a; XML反序列化出錯&#xff0c;XML 文檔(2, 2)中有錯誤二.解決方案&#xff1a; 在實體類的字段要加上XmlElement屬性三.具體實現: 1.XML文檔 <EVENT_INSTANCE><EventType>ALTER_TABLE</EventType><…

iOS--支付寶環境集成

1.下載支付寶SDK以及Demo https://doc.open.alipay.com/doc2/detail?treeId54&articleId103419&docType1 2.新建文件夾“AliSDK”&#xff0c;將壓縮包內的文件拷貝到該文件夾下&#xff0c;完成后如下圖所示&#xff1a; 3.將文件夾拷貝到項目中&#xff0c; 4.執行完…