在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.mzph.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