内置对象和内置函数

尽管模拟对象是进行单元测试的理想工具,但通过模拟框架进行模拟可能会将您的单元测试变成难以维护的混乱。

这种复杂性的根本原因是我们的对象太大。 他们有很多方法,这些方法返回其他对象,这些对象也有方法。 当将此类对象的模拟版本作为参数传递时,我们应确保其所有方法都返回有效对象。

这导致不可避免的复杂性,这使得单元测试浪费几乎不可能维护。

对象层次结构

以jcabi-dynamo的Region接口为例(为简洁起见,此代码段和本文中的所有其他代码段都进行了简化):

public interface Region {Table table(String name);
}

它的table()方法返回Table接口的实例,该实例具有自己的方法:

public interface Table {Frame frame();Item put(Attributes attrs);Region region();
}

frame()方法返回的接口Frame也具有自己的方法。 等等。 为了创建接口Region的正确模拟的实例,通常会创建许多其他模拟对象。 使用Mockito时 ,它将如下所示:

public void testMe() {// many more lines here...Frame frame = Mockito.mock(Frame.class);Mockito.doReturn(...).when(frame).iterator();Table table = Mockito.mock(Table.class);Mockito.doReturn(frame).when(table).frame();Region region = Mockito.mock(Region.class);Mockito.doReturn(table).when(region).table(Mockito.anyString());
}

所有这些只是实际测试之前的脚手架。

样本使用案例

假设您正在开发一个项目,该项目使用jcabi-dynamo来管理DynamoDB中的数据。 您的课程可能类似于以下内容:

public class Employee {private final String name;private final Region region;public Employee(String empl, Region dynamo) {this.name = empl;this.region = dynamo;}public Integer salary() {return Integer.parseInt(this.region.table("employees").frame().where("name", this.name).iterator().next().get("salary").getN());}
}

您可以想象,例如使用Mockito对此类进行单元测试将有多困难。 首先,我们必须模拟Region接口。 然后,我们必须模拟一个Table接口,并确保它由table()方法返回。 然后,我们必须模拟一个Frame接口,等等。

单元测试将比类本身更长。 除此之外,它的真正目的(即测试雇员工资的取回)对读者而言并不明显。

此外,当我们需要测试相似类的相似方法时,我们将需要从头开始重新进行此模拟。 同样,多行代码看起来与我们已经编写的代码非常相似。

假班

解决方案是创建伪造的类并将其与真实的类一起运送。 这就是jcabi-dynamo所做的。 只需查看其JavaDoc即可 。 有一个名为com.jcabi.dynamo.mock的包,其中仅包含伪类,仅适用于单元测试。

即使它们的唯一目的是优化单元测试,我们也将它们与生产代码一起放在同一JAR软件包中。

使用伪类MkRegion时,测试结果如下所示:

public class EmployeeTest {public void canFetchSalaryFromDynamoDb() {Region region = new MkRegion(new H2Data().with("employees", new String[] {"name"},new String[] {"salary"}));region.table("employees").put(new Attributes().with("name", "Jeff").with("salary", new AttributeValue().withN(50000)));Employee emp = new Employee("Jeff", region);assertThat(emp.salary(), equalTo(50000))}
}

这个测试对我来说很明显。 首先,我们创建一个伪造的DynamoDB区域,该区域可在H2Data存储(内存中的H2数据库)之上H2Data 。 该存储将准备好用于具有哈希键name和单个salary属性的单个employees表。

然后,我们在表中放入记录,其中包含哈希Jeff和薪水50000

最后,我们创建一个Employee类的实例,并检查它如何从DynamoDB获取薪水。

我目前正在与几乎所有正在使用的开源库中进行相同的操作。 我正在创建一组伪造的类,以简化库内部及其用户的测试。

相关文章

您可能还会发现以下有趣的帖子:

  • Glenford Myers撰写的软件测试艺术
  • Maven Build中的CasperJS测试
  • Hamcrest的XML / XPath匹配器
  • 错误欢迎
  • Phantomjs作为HTML验证器

翻译自: https://www.javacodegeeks.com/2014/09/built-in-fake-objects.html

内置对象和内置函数

内置对象和内置函数_内置假对象相关推荐

  1. python中函数type可以测试对象类型_Python中type函数type()显示对象的类型,dir函数dir()显示的是对象可用的方法。_学小易找答案...

    [判断题]new_word = word.upper() 这一语句表示将word这个变量的值全部小写并赋给新变量new_word. [单选题]All of the students have fini ...

  2. mysql 内联函数_内联函数 - freeboy小亮 - 博客园

    (1)什么是内联函数? 内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内. (2)为什么要引入内联函数? 当然,引入内联函数的主要目的是:解决程序中函数调用的效率问题.另外,前面我们 ...

  3. java内联函数_Java之内联函数_内联函数的优缺点

    描述 内联函数 1.内联函数就是指函数在被调用的地方直接展开,编译器在调用时不用像一般函数那样,参数压栈,返回时参数出栈以及资源释放等,这样提高了程序执行速度. 2.Java语言中有一个关键字fina ...

  4. c ++内联函数_内联MHTML +数据URI

    c ++内联函数 MHTML and Data URIs in the same CSS file is totally doable and gives us nice support for IE ...

  5. 内的 对象 获取 键值对_前端系列——Object对象数据类型详细剖析

    问题: 普通对象有哪些操作? 什么是数组对象? 回答: 1--解答:普通对象是用{}包裹起来的,由零到多组属性值和属性名组成的一种数据类型.属性是描述当前对象特征的,属性名是当前具备特征的名称,属性值 ...

  6. mysql内连接和外连接的区别_内连接、外连接的区别

    先来看一下,内连接的语法: SELECT  XXX FROM XXX INNER JOIN XXX ON XXX; 这里 INNER 可以省略,在上一篇博客中我们对于笛卡尔积现象的研究中(http:/ ...

  7. linq调用mysql函数_如何为linq对象制作一个展平函数(Linq To Entities for mysql)?

    我正在升级一个旧程序并使用 linq进行基本选择,以便我可以在进程中学习linq. 我有一个重复的任务,只是显示来自各种连接的数据是网格视图, 以下是一个示例 protected void Page_ ...

  8. c中将数组传递给子函数_在C ++中将对象传递给Non-Member函数

    c中将数组传递给子函数 Here, we have to define a Non-Member Function, in which we have to pass an Object to the ...

  9. 内网环境下安装python包_内网环境中,如何快速的安装 py 的依赖包

    20 89 天前 能访问外网的机器: pip install wheel && pip wheel -r requirements.txt --wheel-dir=/svc/wheel ...

最新文章

  1. Integer与int的种种比较你知道多少?[转]
  2. update 后面能接子查询吗_只用身份证能查询CPA成绩吗?查询步骤不能忘
  3. [Java基础]IO流概述和分类
  4. 从头学习linux C 冒泡法排序
  5. Java笔记-CXF增加拦截器与自定义拦截器
  6. mysql语句修改zencart产品原价为特价的倍数
  7. docker 2376端口 CA 认证,并不能阻止服务器成为肉鸡
  8. oracle使用with as提高查询效率
  9. Quartz定时任务调度机制解析(CronTirgger、SimpleTrigger )
  10. DOS系统下控制串口(1)
  11. IT服务及相关概念界定
  12. 【华人学者风采】聂飞平 西北工业大学
  13. 【转载】OceanBase架构介绍
  14. 计算机一级access教程,计算机一级考试Access傻瓜教程.doc
  15. python使用BeautifulSoup爬取2345电影网
  16. 怀揣一颗赤子之心,他回国创业,逐步实现自己的产业梦
  17. linux串口配置驱动程序,Linux下安装PCI转串口卡及USB转串口器的驱动方法
  18. html5有时使用 i 标签做小图标
  19. Android viewpager在scrollview中的滚动问题
  20. UML组件视图、部署图、包图简要说明

热门文章

  1. bzoj1013,luogu4035-[JSOI2008]球形空间产生器【高斯消元】
  2. nssl1254-A(林下风气)【树形dp】
  3. 学习手记(2018/7/14~2018/7/18)——快乐纪中
  4. P3957-跳房子【单调队列,dp,二分】
  5. ssl1762-工厂的烦恼【图论,最短路变形(最长路)】
  6. 【动态规划】石子合并 (ssl 2863)
  7. 组合数学与数论函数专题
  8. 汇编语言(三十三)之四进制转十进制
  9. SaaS,PaaS,IaaS都是什么鬼
  10. Tomcat Get请求的巨坑