一种编写测试的好方法

测试。 最近我一直在考虑进行测试。 作为我对各种项目所做的代码审查的一部分,我已经看到了数千行未经测试的代码。 这不仅是测试覆盖率统计数据指出这一点的情况,还更多是该项目中根本没有任何测试的情况 。 我一直听到这种悲惨状况的两个原因? “我们没有时间”,紧随其后的是“完成代码后就去做”。

我在这里展示的不是万能药。 它涵盖了单元测试,尤其是接口的单元测试。 接口是好东西。 接口定义合同。 接口,无论接口有多少种实现方式,都可以轻松,轻松地进行测试。 让我们看看如何使用此类结构作为示例。

fd98ced9 CustomerService是我们的界面。 为了使示例保持简单,它有两种方法,下面将进行介绍。 注意javadoc-这是描述合同的地方。

public interface CustomerService
{/*** Retrieve the customer from somewhere.* @param userName the userName of the customer* @return a non-null Customer instance compliant with the userName* @throws CustomerNotFoundException if a customer with the given user name can not be found*/Customer get(String userName) throws CustomerNotFoundException;/*** Persist the customer.* @param customer the customer to persist* @return the customer as it now exists in its persisted form* @throws DuplicateCustomerException if a customer with the user name already exists*/Customer create(Customer customer) throws DuplicateCustomerException;
}

从图中可以看到,我们有两个此类的实现,RemoteCustomerService和CachingCustomerService。 这些的实现没有显示,因为它们无关紧要。 我怎么说呢 很简单–我们正在测试合同。 我们为接口中的每个方法以及合同的每个排列编写测试。 例如,对于get(),我们需要测试存在具有给定用户名的客户时发生的情况,以及不存在时发生的情况。

public abstract class CustomerServiceTest
{@Testpublic void testCreate(){CustomerService customerService = getCustomerService();Customer customer = customerService.create(new Customer("userNameA"));Assert.assertNotNull(customer);Assert.assertEquals("userNameA",customer.getUserName());}@Test(expected = DuplicateCustomerException.class)public void testCreate_duplicate(){CustomerService customerService = getCustomerService();Customer customer = new Customer("userNameA");customerService.create(customer);customerService.create(customer);}@Testpublic void testGet(){CustomerService customerService = getCustomerService();customerService.create(new Customer("userNameA"));Customer customer = customerService.get("userNameA");Assert.assertNotNull(customer);Assert.assertEquals("userNameA",result.getUserName());}@Test(expected = CustomerNotFoundException.class)public void testGet_noUser(){CustomerService customerService = getCustomerService();customerService.get("userNameA");}public abstract CustomerService getCustomerService();
}

现在,我们已经对合同进行了测试,并且在任何时候都没有提到任何实现。 这意味着两件事:

  • 我们不需要为每个实现重复测试。 这是一件非常好的事情。
  • 没有一个实现正在测试中。 我们可以通过为每个实现添加一个测试类来纠正此问题。 由于每个测试类几乎都是相同的,因此我将仅演示RemoteCustomerService的测试。
public class RemoteCustomerServiceTest extends CustomerServiceTest
{public CustomerService getCustomerService(){return new RemoteCustomerService();}
}

就是这样! 现在,我们有了一种非常简单的方法来测试任何接口的多个实现,方法是预先进行艰苦的工作,并将测试新实现的工作减少到一个简单的方法中。

参考: Objective博客上的JCG合作伙伴 Steve Chaloner 编写测试的一种好方法 。

翻译自: https://www.javacodegeeks.com/2013/06/a-good-lazy-way-to-write-tests.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rem、px、em之间的区别以及网页响应式设计写法

个人收藏用,转载自:http://www.w3cplus.com/css3/define-font-size-with-css3-rem 在Web中使用什么单位来定义页面的字体大小,至今天为止都还在激烈的争论着,有人说PX做为单位好,有人说EM优点多,还有人在说…

游戏服务器架构图

1:ARPG类型游戏 2:MMORPG 3:MOBA 4:卡牌类 5:棋盘类 转载于:https://www.cnblogs.com/like-minded/p/8297718.html

GlassFish 4带来了Java EE 7

真是惊喜 除了推出新的iOS 7外,苹果在wwdc上什么也没提供。 碰巧的是,在他们的主题演讲后不久,又有7个人正式露面。 GlassFish 4.0已于昨天晚上发布(显然是不需要的)。 新的Java EE 7参考实现自动成为当今第一个可用的…

bootstrap的栅格布局与两列布局结合使用

在工作中我们常常需要实现响应式布局,这个可以使用bootstrap的栅格系统来实现,我们在列里也需要实现一部分的响应式。比如下面的效果图,需要实现左边图标固定,右边的自适应 : 左边固定宽度,右边自适应&…

JVM性能魔术技巧

HotSpot是我们众所周知和喜爱的JVM,是Java和Scala汁流淌的大脑。 多年来,许多工程师对其进行了改进和调整,并且在每次迭代中,其代码执行的速度和效率都接近本机编译代码。 JIT(“即时”)编译器是其核心。…

mysql 10个日期,MySQL自学篇(10)——日期函数

MySQL自学篇(十)——日期函数日期和时间函数(1)获取当前日期的函数和时间的函数CURDATE()和CURRENT_DATE()函数,获取当前日期select current_date(),curdate(),curdate()0;curdate()0 表示将当前时间转化为数值型CURTIME()和CURRENT_TIME()获取当前时间select cur…

python-flask-请求源码流程

启动先执行manage.py 中的 app.run() class Flask(_PackageBoundObject):   def run(self, hostNone, portNone, debugNone, **options):from werkzeug.serving import run_simpletry:#run_simple 是werkzeug 提供的方法,会执行第三个参数 self()run_simple(ho…

正则表达式强化,爬虫练习

re模块下的常用方法 import re ret re.findall(\d(\.\d)?, 1.232.34)   print(ret) 结果: [.23,.34] # findall的正则表达式里面有分组(),()里面的内容优先显示 ret re.findall(\d(?:\.\d)?, 1.232.34)print(ret)    结果:…

Linux LVM管理

LVM(Logical Volume Manager)逻辑卷管理是在Linux2.4内核以上实现的磁盘管理技术。它是Linux环境下对磁盘分区进行管理的一种机制。 本文内容: 创建和管理LVM扩容LVM分区一、创建和管理LVM 要创建一个LVM系统,一般需要经过以下步骤: 1、 创建…

USB OTG插入检测识别

一 USB引脚一般四根线,定义如下: 为支持OTG功能,mini/micro usb接口扩展了一个ID引脚(第4脚) A设备端ID脚接地,则初始状态为Host,例如PC和支持OTG设备做主设备时 B设备端ID脚悬空,默…

CSS3与页面布局学习笔记(三)——BFC、定位、浮动、7种垂直居中方法

一、BFC与IFC 1.1、BFC与IFC概要 BFC(Block Formatting Context)即“块级格式化上下文”, IFC(Inline Formatting Context)即行内格式化上下文。常规流(也称标准流、普通流)是一个文档在被显示…

Java垃圾回收(2)

并行清理 今天,我们介绍了并行GC的工作原理。 具体来说,这是在Eden上运行Parallel Scavenge收集器,在Tenured一代中运行Parallel Mark and Sweep收集器的组合。 您可以通过传递-XX: UseParallelOldGC来获得此选项,尽管…

Navicat Premium创建MySQL存储过程

1、使用Navicat Premium打开创建函数向导,操作:连接名——数据库——函数——新建函数 2、选择过程——输入存储过程参数——完成(这一步可以不填写参数,编写存储过程代码的时候设置参数) 3、按照要求完成存储过程代码…

CSS3与页面布局学习笔记(二)——盒子模型(Box Model)、边距折叠、内联与块标签、CSSReset

一、盒子模型(Box Model) 盒子模型也有人称为框模型,HTML中的多数元素都会在浏览器中生成一个矩形的区域,每个区域包含四个组成部分,从外向内依次是:外边距(Margin)、边框&#xff…

mysql中将某个字段做计算,mysql创建计算字段使用子查询教程

作为计算字段使用子查询使用子查询的另一方法是创建计算字段。假如需要显示 customers表中每个客户的订单总数。订单与相应的客户ID存储在 orders 表中。为了执行这个操作,遵循下面的步骤。(1) 从 customers 表中检索客户列表。(2) 对于检索出的每个客户&#xff0c…

Android GreenDao使用教程

一、Greendao简介 Greendao是一款用于数据库创建与管理的框架,由于原生SQLite语言比较复杂繁琐,使得不少程序员不得不去学习SQLite原生语言,但是学习成本高,效率低下,所以不少公司致力于开发一款简单的数据库管理框架&…

Java垃圾回收(1)

这是有关垃圾收集(GC)的系列文章中的第一篇。 我希望能够涵盖整个系列过程中的理论知识以及热点虚拟机中的所有主要收集器。 这篇文章仅说明什么是垃圾回收,以及不同回收器共有的元素。 我为什么要在乎? 您的Java虚拟机可以为您管…

少锁定Java对象池

自从我写任何东西以来已经有一段时间了,我一直在忙于我的新工作,该工作涉及在性能调整方面做一些有趣的工作。 挑战之一是减少应用程序关键部分的对象创建。 尽管Java随着时间的推移改进了GC算法,但垃圾回收打h一直是Java的主要难题。 Azul是…

php数据库postgresql,PHP 操作 PostgreSQL数据库

1.要让PHP支持PostgreSQL,就需要重新编译PHP;./configure --prefix/usr/local/php5 --with-apxs2/usr/local/apache2/bin/apxs --with-mysql/usr/local/mysql --with-config-file-path/usr/local/php5 --with-zlib --enable-mbstringall --with-mysql…

uestc summer training #2

A 增广 #include<bits/stdc.h> using namespace std; const int MAXN 1000000 10; vector<int> g[MAXN]; int a[MAXN], b[MAXN], sz[MAXN], cnt[MAXN]; bool mg[MAXN], vis[MAXN]; int n, m; bool dfs(int u, int f -1) {if (g[u].empty()) //如果当前数没有位…