摘自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

测试抽象类和模板方法模式相关推荐

  1. java抽象类和模板模式_测试抽象类和模板方法模式

    java抽象类和模板模式 摘自Wikipedia,"模板方法定义了算法的程序框架. 子类可以覆盖一个或多个算法步骤,以允许不同的行为,同时确保仍然遵循总体算法." 通常,此模式由两 ...

  2. 抽象类和模板方法模式

    抽象方法和抽象类 抽象类:用abstract修饰符修饰的类,如: public abstract class GeneralService {} 抽象方法:用abstract修饰符修饰的方法,抽象方法 ...

  3. Java:抽象方法和抽象类,抽象类应用模板方法模式,接口及使用

    一.抽象类概念和作用 抽象类                 Java中可以定义没有方法体的方法,该方法由子类来具体实现.                 该没有方法体的方法我们称之为抽象方法,含有抽 ...

  4. 抽象类应用——模板方法模式

    2019独角兽企业重金招聘Python工程师标准>>> 模板方法模式(Templete Method):定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中.模板方法模式使 ...

  5. Java描述设计模式(19):模板方法模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 通常一款互联网应用的开发流程如下:业务需求,规划产品,程序开发,测试交付.现在基于模板方法模式进行该过程描述. public c ...

  6. Java设计模式-模板方法模式详解

    Java设计模式-模板方法模式 文章目录 Java设计模式-模板方法模式 0.前言 1.模板方法原理 2.模板方法模式中的角色 3.模板方法模式的UML类图 4.代码实现 5.编码测试 6.模板模式中 ...

  7. 设计一个扩展自抽象类geometricobject_设计模式4之模板方法模式

    背景 在开发中,你肯定有遇到过这样一种场景:你知道某个方法的关键步骤以及执行顺序,但是里面有的具体步骤并清楚.你会怎么做? 比如你早上起床到公司,我们分解步骤: "起床洗漱吃早餐乘坐交通工具 ...

  8. Java抽象类:案例、特点、模板方法模式

    一.抽象类的案例 案例:加油站支付卡  系统需求: 某加油站推出了2种支付卡: 1.预存1万元的金卡,后续加油享受8折优惠: 2.预存5千元的银卡,后续加油享受8.5折优惠. 请分别实现2种卡片进入收 ...

  9. JAVA基础13-Java抽象方法、抽象类、抽象之模板方法模式

    文章目录 Java抽象方法和抽象类 抽象之模板方法模式 Java抽象方法和抽象类 抽象类: Java中可以定义没有方法体的方法,该方法由子类来具体实现.这个没有方法体的方法我们称之为抽象方法,含有抽象 ...

最新文章

  1. mysql的表空间是否自动扩展_Oracle修改指定表空间为自动扩展
  2. python知识点 07-11
  3. python中rename函数_python os.rename(…)不起作用!
  4. 虎牙直播在微服务改造方面的实践和总结
  5. PAT甲级1003 Emergency:[C++题解]dijkstra求最短路、最短路条数
  6. 计算机系统备份的原则和策略,计算机系统数据备份机制与策略
  7. 彻底理解mysql服务器的字符集转换问题
  8. Exchange管理之:使用Telnet发送邮件
  9. 53 - 9. 回文数
  10. maven使用中央仓库没有的jar包001---Maven自定义上传第三方包到3rd party(第三方无依赖jar和本地扩展类加入maven统一管理)
  11. 在react或vue中,for循环用Index作为key值是好还是坏呢?
  12. 巧用 Nginx 快速实现 HTTPS 双向认证
  13. [转]static和final的区别
  14. Opencv实现的简易绘图工具
  15. EXPLOITING CVE-2016-2060 ON QUALCOMM DEVICES
  16. #C语言#6.1 数据类型 笔记
  17. 【读报告】基于物联网技术的道岔转换设备检测专家平台的研究 研制报告
  18. 从PCB制造工艺参数到AD规则设置
  19. java计算机毕业设计框架的电脑测评系统源程序+mysql+系统+lw文档+远程调试
  20. 有关Steam上CSGO游戏闪退

热门文章

  1. foreach 循环详解
  2. HDU2612(BFS算法)
  3. java使用迭代器删除元素_使用Java从地图中删除元素
  4. 不停机与停机更新_Istio的零停机滚动更新
  5. rx.observable_使用Java 8 CompletableFuture和Rx-Java Observable
  6. 异步http 超时_具有CompletableFuture的异步超时
  7. javafx canvas_JavaFX技巧1:可调整大小的Canvas
  8. spring创建web项目_使用Spring WS创建合同优先的Web服务
  9. 与时俱进:在JAX-RS API中采用OpenAPI v3.0.0
  10. 固定速率与固定延迟– RxJava常见问题解答