高效的企业测试-单元和用例测试(2/6)

在本系列的第一部分中,我们看到了有效测试应满足的一些普遍适用的原则和约束。 在这一部分中,我们将仔细研究代码级单元测试以及组件用例测试。

单元测试

单元测试验证单个单元(通常是类)的行为,而忽略或模拟该单元外部的所有问题。 单元测试应测试各个单元的业务逻辑,而不验证其进一步的集成或配置。

根据我的经验,大多数企业开发人员对单元测试的构建方式都有很好的了解。 您可以在我的咖啡测试项目中查看此示例,以了解想法。 大多数项目将JUnit与Mockito结合使用以模拟依赖关系,理想情况下使用AssertJ来有效定义可读的断言。 我一直认为,我们可以执行单元测试而无需特殊的扩展程序或运行程序,即仅使用纯JUnit运行它们。 原因很简单:执行时间; 我们应该能够在几毫秒内运行数百个测试。

单元测试通常执行速度非常快,并且易于执行,并且不会对测试套件的生命周期施加任何约束,因此可以轻松支持构建复杂的测试套件或特殊的开发工作流程。

但是,具有许多模拟被测类的依赖关系的单元测试的缺点是,它们将与实现紧密结合,尤其是类结构和方法,这使得重构代码变得困难。 换句话说,对于生产代码中的每个重构动作,测试代码也需要更改。 在最坏的情况下,这会导致开发人员进行较少的重构,这仅仅是因为它们变得太麻烦了,从而很快导致项目代码质量下降。 理想情况下,开发人员应该能够重构代码并四处移动,只要他们不改变应用程序的行为(从用户的角度来看)即可。 单元测试并不总是使重构生产代码变得容易。

根据项目经验,单元测试对于测试具有简洁逻辑或功能的高密度代码(例如特定算法的实现)非常有效,同时又不会与其他组件发生过多交互。 特定类中的代码密度越小或越复杂,循环复杂性越低,或者与其他组件的交互作用越高,则测试该类的单元测试效果就越差。 尤其是在具有少量专业业务逻辑并且与外部系统的集成程度相当的微服务中,可以说,对许多单元测试的需求减少了。 除了少数例外,这些系统的各个单元通常包含很少的专用逻辑。 选择在哪里花时间和精力进行权衡时,必须考虑到这一点。

用例测试

为了解决将测试与实现紧密耦合的问题,我们可以使用略有不同的方法来扩大测试范围。 在我的书中 ,我描述了组件测试的概念,因为缺少更好的术语,我们也可以将其称为用例测试。

用例测试是代码级别的集成测试,由于测试启动时间的原因,它们还没有使用嵌入式容器或反射扫描。 他们验证通常参与单个用例的一致组件的业务逻辑行为,从边界的业务方法一直到所有涉及的组件。 与外部系统(如数据库)的集成已被嘲笑。

在不使用更先进的技术自动建立组件连接的情况下构建此类方案听起来很费力。 但是,我们定义了可重用的测试组件或test double ,它们通过模拟,接线和测试配置来扩展组件,以最大程度地减少重构变更的整体工作量。 目标是制定单一职责,以将变更的影响限制在测试范围内的单个或几个类中。 以可重复使用的方式执行此操作会限制总体所需的工作量,并且在项目规模变大时会得到回报,因为我们每个组件只需支付一次管道费用,这很快就可以摊销。

为了获得更好的主意,假设我们正在测试订购咖啡的用例,其中包括两个类CoffeeShopOrderProcessor

测试双重类CoffeeShopTestDoubleOrderProcessorTestDouble*TD驻留在项目的测试范围中,而它们扩展了驻留在主要范围中的CoffeeShopOrderProcessor组件。 测试双打可能会设置所需的模拟和连线逻辑,并可能使用与用例相关的模拟或验证方法来扩展类的公共接口。

下面显示了CoffeeShop组件的测试double类:

 public class CoffeeShopTestDouble extends CoffeeShop { public CoffeeShopTestDouble(OrderProcessorTestDouble orderProcessorTestDouble) { entityManager = mock(EntityManager. class ); orderProcessor = orderProcessorTestDouble; } public void verifyCreateOrder(Order order) { verify(entityManager).merge(order); } public void verifyProcessUnfinishedOrders() { verify(entityManager).createNamedQuery(Order.FIND_UNFINISHED, Order. class ); } public void answerForUnfinishedOrders(List<Order> orders) { // setup entity manager mock behavior }  } 

测试double类可以访问CoffeeShop基类的字段和构造函数以设置依赖项。 它使用其测试双重形式的其他组件(例如OrderProcessorTestDouble )来能够调用用例中包含的其他模拟或验证方法。

测试双重类是可重用的组件,在每个项目范围内编写一次,并在多个用例测试中使用

 class CoffeeShopTest { private CoffeeShopTestDouble coffeeShop; private OrderProcessorTestDouble orderProcessor; @BeforeEach void setUp() { orderProcessor = new OrderProcessorTestDouble(); coffeeShop = new CoffeeShopTestDouble(orderProcessor); } @Test void testCreateOrder() { Order order = new Order(); coffeeShop.createOrder(order); coffeeShop.verifyCreateOrder(order); } @Test void testProcessUnfinishedOrders() { List<Order> orders = Arrays.asList(...); coffeeShop.answerForUnfinishedOrders(orders); coffeeShop.processUnfinishedOrders(); coffeeShop.verifyProcessUnfinishedOrders(); orderProcessor.verifyProcessOrders(orders); }  } 

用例测试验证在入口点(这里为CoffeeShop上调用的单个业务用例的处理。 这些测试变得简短且易读,这是因为接线和模拟发生在单个测试双打中,并且它们还可以利用特定于用例的验证方法,例如verifyProcessOrders()

如您所见,测试双重扩展了生产范围类,用于设置模拟和验证行为的方法。 尽管这似乎是一些设置工作,但如果我们有多个用例可以在整个项目中重用组件,则成本将快速摊销。 我们的项目增长得越多,这种方法的好处就越大,尤其是当我们查看测试执行时间时。 我们所有的测试用例仍然使用JUnit运行,它可以立即执行数百个测试用例。

这是这种方法的主要优点:用例测试的运行速度与普通单元测试一样快,但由于仅需对单个或几个组件进行更改,因此可以方便地重构生产代码。 此外,使用针对我们领域的富有表现力的设置和验证方法来增强测试效率,从而使我们的测试代码更具可读性,便于使用,并避免了测试案例中的样板代码。

不包含任何高级测试上下文运行程序的代码级测试可以非常快速地执行,并且即使在非常复杂的项目中也不会为整体构建增加太多时间。 该系列的下一部分将显示代码级以及系统级集成测试。

翻译自: https://www.javacodegeeks.com/2019/09/efficient-enterprise-testing-unit-use-case.html

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

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

相关文章

搜狗输入法更换字体与皮肤

图标上右键-更多-属性设置 效果&#xff1a; 注意&#xff1a;如果是新安装的字体&#xff0c;更换中文字体但其中列表没有显示&#xff0c;可以取消更换字体前面的对钩后&#xff0c;重新选择对钩&#xff0c;此时就显示新的中文字体了

javafx 8u40_JavaFX 8u20天的未来过去(始终在最前面)

javafx 8u40自从我发布有关JavaFX的主题以来已经有很长时间了。 因此&#xff0c;如果您仍在追随&#xff0c;那就太棒了&#xff01; 介绍 在这篇博客文章中&#xff0c;我想写一篇关于从JavaFX 8 update 20开始的非常酷的功能的博客&#xff0c;该功能使您的应用程序始终位于…

如何在内存序列化中使用Java深克隆对象

在我以前的文章中&#xff0c;我解释了深度克隆和浅层克隆之间的区别 &#xff0c; 以及复制构造函数和防御性复制方法比默认的Java克隆更好。 使用复制构造函数和防御性复制方法进行的Java对象克隆当然具有某些优势&#xff0c;但是我们必须显式编写一些代码才能在所有这些方…

复制网页内容

问题背景&#xff1a; 当网页复制东西时&#xff0c;可能因为某些原因导致无法复制。可以用以下方法解决 解决方法&#xff1a; 1. 按下F12&#xff0c;出现以下内容 2. 依次点击右上角三个点&#xff0c;弹出界面后点击shortcuts 3. 选择首选项后&#xff0c;选中Disable …

插入时间信息

问题描述 在进行文本编辑的时候&#xff0c;往往需要记录当天日期。而Typora等软件没有及时插入时间的快捷方式。 方法 搜狗收入法提供快速记录时间的方式 1. 在中文输入法模式中输入rq&#xff08;汉语拼音日期的首字母&#xff09;&#xff0c;选项卡自动显示今日日期,可…

activemq网络桥接_ActiveMQ –经纪人网络解释–第4部分

activemq网络桥接在前面的第3部分中 &#xff0c;我们已经看到ActiveMQ如何帮助将远程使用者与本地使用者区分开来&#xff0c;这有助于确定从消息生产者到使用者的较短路径。 在第4部分中&#xff0c;我们将研究如何在远程代理上负载均衡并发使用者。 让我们考虑一些高级配置…

sublime 添加注释模块

问题背景&#xff1a; 规范的程序需要对函数进行注释&#xff0c;常用的开发工具如IDEA、VS Code都对注释模板有很好的支持。本博客介绍Sublime下支持模块注释功能的设置。 一 安装 一、安装方法 1.安装docblocker插件 mac CmdShiftP -> Install Package -> docblock…

只读副本和Spring Data第3部分:配置两个实体管理器

我们之前的设置可以正常工作。 我们现在要做的是进一步发展&#xff0c;并配置两个单独的实体管理器&#xff0c;而不会影响我们之前实现的功能。 第一步是将默认的实体管理器配置设置为主要配置。 这是第一步 package com.gkatzioura.springdatareadreplica.config; import…

Win+E快速打开我的电脑方式设置方式

W10运用快捷键WinE快速打开我的电脑设置方式

JMetro版本11.6.5和8.6.5发布

再一次问好。 设置了SDK中所有JavaFX控件的样式以及其他一些不存在的样式以及其他库中的其他样式。 后续版本将涉及调整JMetro现有样式或从第三方库的其他控件添加其他样式。 此版本就是这种情况。 这是新功能&#xff1a; 3种新的控件样式&#xff1b; 调整JMetro现有样式&a…

Chrome浏览器的便捷使用方式

截取转载于B站视频【全套教程】高效玩转Chrome浏览器&#xff0c;丰富你的上网体验_哔哩哔哩_bilibili中的脑图文件&#xff0c;便于之后的熟悉使用。 脑图链接 https://naotu.baidu.com/file/5a5332eee10dd903cc084d49189cd2behttps://naotu.baidu.com/file/5a5332eee10dd90…

Sublime查看已经安装的插件

蓝色框图内显示已经安装的插件

activemq网络桥接_ActiveMQ –经纪人网络解释–第3部分

activemq网络桥接现在&#xff0c;我们已经在本博客系列的第1部分和第2 部分中了解了ActiveMQ网络连接器的基础&#xff0c;在第3部分中&#xff0c;我们将研究ActiveMQ如何平衡连接到代理网络的使用者。 介绍 当可以无序处理队列中的消息时通常使用并发使用者&#xff0c;通常…

Word样式的导入与导出

1 样式的介绍 样式&#xff0c;也就是Word中各级标题的格式。合理的设置样式模板&#xff0c;可以帮助更方便的进行文本编辑。 2 样式的导入 具体情形为将“文档标准模板.dotm”的内容应用于“新建Microsoft Word文档”。 按照图示进行操作 【 如果应用模板为文件内的样式…

word将一个文档的样式导入到另一个文档

一、背景 在word中编辑文档时&#xff0c;经常需要定义一个样式给特定格式的文本使用&#xff0c;如标题1&#xff0c;标题2等&#xff0c;而有时需要在一个新文档A中使用一个旧文档B中定义好的样式。 二、操作步骤 1、打开旧文档B&#xff0c;选择上方标签栏的"样式&quo…

Spring Boot应用程序浪费了内存

内存是当今世界上被广泛浪费的资源之一。 由于编程效率低下&#xff0c;令人吃惊的&#xff08;有时是“令人震惊的”&#xff09;内存浪费被浪费了。 我们看到这种模式在多个企业应用程序中重复出现。 为了证明这种情况&#xff0c;我们进行了一项小型研究。 我们分析了著名的…

Win10灵活使用快速访问

I 快速访问视图 位置在winE 左侧窗口&#xff0c;点击可快速到达某个特定的文件夹。作用类似于快捷方式&#xff0c;操作简单。 II 关闭自动添加 默认是显示经常使用的文件夹。这使得窗口内文件夹较乱。 通过以下设置&#xff0c;关闭自动显示 1. 2.把框内√去掉 III 固定文…

activemq网络桥接_ActiveMQ –经纪人网络解释–第2部分

activemq网络桥接在此博客中&#xff0c;我们将看到双工网络连接器如何工作。 在上一部分中&#xff0c;我们从broker-1和broker-2创建了一个网络连接器。 我们能够看到&#xff0c;当代理2上有一个使用者使用队列“ foo.bar”时&#xff0c;代理1上的队列“ foo.bar”的消息如…

Apache Lucene中的并发查询执行

Apache Lucene是一个出色的并发纯Java搜索引擎&#xff0c;如果您愿意&#xff0c;它可以轻松地使服务器上的可用CPU或IO资源饱和。 “典型” Lucene应用程序的并发模型在搜索时每个查询一个线程&#xff0c;但是您知道Lucene还可以使用多个线程同时执行一个查询以大大减少最慢…

Windows设置自己的程序开机自动启动

Windows系统想要快速设置开机自动启动某个程序&#xff0c;可以使用以下方法设置&#xff1a; 1.找到启动文件夹 CtrlR 打开运行&#xff0c;输入shell:startup&#xff0c;回车,找到启动文件夹 2.拷贝需要开机启动的程序的快捷方式到此文件夹即可。 3.打开任务管理器-启动查…