这并不是要成为技术含量很高的职位。 这篇文章的目的是为您提供一些指导,以使您的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

在JUnit测试中使用Builder模式相关推荐

  1. idea使用junit测试_在JUnit测试中使用Builder模式

    idea使用junit测试 这并不是要成为技术含量很高的职位. 这篇文章的目的是为您提供一些指导,以使您的JUnit测试生活更加轻松,使您能够在几分钟内编写复杂的测试场景,并获得具有高度可读性的测试. ...

  2. 浅谈Junit测试中反射和Jmock的应用

    最近由于项目的需要,开发后的代码强制编写Junit测试,并且达到一定的coverage probility(主要应付客户).所以,为了达到一定的覆盖率,鄙人不得不在Case中大量使用反射(一般是针对p ...

  3. java如何保存初始化数据_java – 如何在JUnit测试中初始化数据

    我的任务是为服务层编写压力(负载)测试.主要是CRUD操作.我们使用JUnit作为测试框架,使用JUnitPerf构建负载测试,使用 Spring注入服务bean,使用hibernate访问数据库. ...

  4. Junit测试中找不到junit.framework.testcase

    在使用Junit进行测试时,出现如下问题: 找不到junit.framework.testcase 解决方法: 选中项目->属性->Java构建路径->库->添加外部jar 在 ...

  5. Eclipse中Junit测试中@Before不执行

    场景 在使用Junit进行单元测试时,一部分获取JPA的entityManager的代码将其放在了 @Before标注的方法中,这样每次执行@TEST标注的方法时会首先执行@Before标注的方法. ...

  6. android builder模式 插件,如何在Kotlin中实现Builder模式?

    首先,在大多数情况下,您不需要在Kotlin中使用构建器,因为我们有默认和命名参数 . 这使您可以写 class Car(val model: String? = null, val year: In ...

  7. java中的builder模式

    import android.text.TextUtils;/*** Created by toothwind on 2017/7/19.* you can contact me at : tooth ...

  8. springmvc通过@Value注解读取Properties配置文件的值,junit测试可以取到值,但是在业务中无法读取

    最近试着做了个springmvc 项目,在加入 发邮件 功能时遇到的问题. Spring 通过注解获取*.porperties文件的内容,除了xml配置外,还可以通过@value方式来获取. @val ...

  9. 设计模式学习笔记——建造者(Builder)模式

    设计模式学习笔记--建造者(Builder)模式 @(设计模式)[设计模式, 建造者模式, builder] 设计模式学习笔记建造者Builder模式 基本介绍 建造者案例 类图 实现代码 Build ...

最新文章

  1. java包装_Java基础之神奇的包装类(一)
  2. 背水一战 Windows 10 (65) - 控件(WebView): 对 WebView 中的内容截图, 通过 Share Contract 分享 WebView 中的被选中的内容...
  3. (转)Windows7 “上帝模式”的原理
  4. spark 资源参数调优
  5. 【回文自动机】bzoj3676 [Apio2014]回文串
  6. Github中Tag的使用
  7. 计算机图形学Web前端笔记-浏览器中心点转场景坐标理论及实现(two.js)
  8. Android中XML数据解析
  9. 面试被问项目上线没_面试官的最爱问“分布式”核心设计问题,没掌握的不妨来看看...
  10. MFC中显示一张位图
  11. android webview 百度地图,Android WebView显示地图
  12. RouterOS 动态IP接入上网设置教程(超详细)
  13. 阿帕虎题库管理系统服务器,阿帕虎题库管理系统
  14. 航天金税开票导入导出txt格式
  15. 计算器算贝塞尔公式_我不是灯光设计师,但是我会算空间的平均照度
  16. ACCESS入门教程(五)数据的类型和属性
  17. django学习日志(模板的渲染过程)第八部分:字符串数据转义
  18. WPF 加载PDF文件
  19. python打开sql,Python打开Microsoft SQL Server MDF文件
  20. 数据分析学习笔记(二)数据分析三思维七技巧

热门文章

  1. linux-basic(12)正则表达式与文件格式化处理
  2. 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)
  3. ubuntu系统下安装docker并部署Springboot+mysql+redis
  4. 双列集合Map的实现类
  5. 分解因数 递归_递归分解WAR文件
  6. groovy lambda_Java Lambda流和Groovy Clouse的比较
  7. php cdi_本机CDI限定词:@Any和@Default
  8. 设计模式适配器模式_21世纪的设计模式:适配器模式
  9. java多线程 异常处理_Java8多线程ForkJoinPool:处理异常
  10. java 从未导入_Java 8的10个您从未听说过的功能