只能在测试中注射吗?

本文是关于测试设计和可测试性的一些想法。 我们与我的儿子讨论了一些问题,他的儿子是Java的初级开发人员,目前在匈牙利的EPAM(我工作的同一家公司,但在另一家子公司)工作和学习。 本文中的所有内容都是不错的旧知识,但是,您仍然可以在其中找到一些有趣的东西。 如果您是初中生,那么就是这个原因。 如果您是大四学生,那么您将获得一些有关如何解释这些事情的想法。 如果都不是:对不起。

问题简介

他们要做的任务是一些轮盘赌程序或其他游戏模拟代码,他们必须编写。 代码的输出是损失或赢得的模拟钱数。 该模拟使用随机数生成器。 在进行测试时,该生成器引起了头痛。 (是的,您是对的:问题的根本原因是缺乏TDD。)代码的行为是随机的。 有时,模拟玩家赢得了比赛,而其他时候却输了。

使它可测试:注入模拟

如何使此代码可测试?

答案应该很明显:模拟随机数生成器。 利用注入的随机源,并在测试过程中注入不同的非随机源。 在测试期间,随机性并不重要,因此无需测试随机性。 我们必须相信随机数生成器是好的(不是,它永远不会好,也许足够好,但这是完全不同的故事),并且已经由其自己的开发人员进行了测试。

学习#1:不要测试依赖项的功能。

我们可以将Supplier类型的字段初始化为() -> rnd() lambda之类的字段,如果进行测试,则使用setter覆盖它。

可测试的好吗?

现在,我们更改了类的结构。 我们打开了一个新条目,以注入一个随机数生成器。 这个可以吗?

没有普遍的是或否的答案。 这取决于要求。 程序员喜欢使其代码可配置,并且比当前要求所绝对需要的代码更具通用性。 原因……好吧……我想,这是因为过去,程序员多次经历了需求的变化(开玩笑!),并且如果为变化做好了准备的代码,那么编码工作就变得容易了。 这是足够合理的推理,但其中存在一些基本缺陷。 程序员不知道将来会出现什么样的需求。 通常,没有人真正知道,每个人对此都有一些想法。

程序员通常知识最少。 他们怎么知道未来? 业务分析师了解得更好一些,并且在链的末端,用户和客户最了解它。 但是,即使他们也不知道自己无法控制的业务环境也可能需要程序的新功能。

另一个缺陷是,开发未来需求现在会产生很多开发人员无法理解的额外成本。

实践表明,这种“提前”思考的结果通常是几乎不需要的复杂代码和灵活性。 甚至有一个缩写词: YAGNI ,“您将不需要它”。

那么,实现该可注射性功能是否为YAGNI? 一点也不。

首先:代码有许多不同的用途。 执行只是一个。 同样重要的是代码的维护。 如果无法测试该代码,则无法可靠地使用它。 如果无法测试代码,则无法对其进行可靠的重构,扩展:维护。

仅用于测试的功能就像房子的屋顶桥。 您在房屋中时不会自己使用它,但是如果没有它们,检查烟囱将非常困难且昂贵。 没人质疑这些屋顶桥的必要性。 它们是必需的,它们是丑陋的,而且仍然存在。 没有他们,房子就无法测试。

学习#2:可测试的代码通常具有更好的结构。

但这不是唯一的原因。 通常,当您创建可测试的代码时,最终结构通常也将更有用。 也就是说,可能是因为测试模仿了代码的使用,而设计可测试的代码将促使您将可用性放在第一位,将实现放在第二位。 而且,说实话:没有人真正在乎实施。 可用性是目标,实现只是实现目标的工具。

责任

好的,我们做到了:可测试性很好。 但是,还有一个关于责任的问题。

随机性的来源应该硬连接到代码中。 代码和代码的开发者负责随机性。 不是因为这个开发者实现了它,而是因为这个开发者选择了随机数生成器库。 选择基础库是一项重要的任务,必须负责任地完成。 如果我们打开一扇门改变随机性的实现选择,那么我们将失去对我们责任的控制。 还是不是?

是的,没有。 如果您打开API并提供了注入依赖项的可能性,那么您就不必对注入的功能的运行负责。 尽管如此,用户(您的客户)仍会来找您寻求帮助和支持。

“有一个bug!” 他们抱怨。 是因为您的代码还是用户选择的特殊注入实现中的某些内容?

您基本上有三个选择:

  1. 您可以检查每种情况下的错误,并在错误不是您的错误时告诉他们,并帮助他们选择更好的(或只是默认的)函数实现。 这将花费您宝贵的时间,无论是已付还是未付。
  2. 同时,您也可以排除问题并说:您甚至不会检查使用标准的默认实现无法复制的任何错误。
  3. 从技术上讲,您只能使用仅用于可测试性的功能。

第一种方法需要良好的销售支持,否则您最终将花费个人时间解决客户问题,而不是花费您的付费客户时间。 不专业。

第二种方法是专业的,但客户不喜欢它。

第三是将用户从#1吸引到#2的技术解决方案。

学习#3:提前考虑用户的期望。

无论选择哪种解决方案,重要的事情都是有意识地做到,而不仅仅是偶然。 了解您的用户/客户可能会想到什么并做好准备。

防止生产注入

当您打开将随机性生成器注入代码的可能性时,如果确实需要,如何为生产环境关闭那扇门?

我首选的第一个解决方案是,首先不要将其打开。 通过具有lambda表达式(或其他方式)的初始化字段使用该表达式,使其可以注入,但不实现注入支持。 让该字段为私有字段(但不是最终字段,因为在这种情况下可能会导致其他问题),并在测试中进行一些反思以更改私有字段的内容。

另一个解决方案是提供一个包私有的setter,或者更好的方法是提供一个额外的构造函数来更改/初始化字段的值,并在生产环境中使用它时引发异常。 您可以检查很多不同的方式:

  • 为生产环境中不在类路径上的测试类调用`Class.forName()`。
  • 使用`StackWalker`并检查调用者是否为测试代码。

为什么我更喜欢第一个解决方案?

学习#4:不要仅仅因为可以就使用花哨的技术解决方案。 无聊通常会更好。

首先,因为这是最简单的方法,所以会将所有测试代码放入测试中。 应用程序代码中的设置程序或特殊构造函数本质上是测试代码,而生产代码中则包含它们的字节代码。 测试代码应在测试类中,生产代码应在生产类中。

第二个原因是设计功能在生产环境和测试环境中故意有所不同,这恰恰违背了测试的基本原理。 测试应在经济上尽可能模拟生产环境。 当测试环境不同时,您如何知道代码将在生产环境中正常工作? 你希望。 已经有许多环境因素可能会改变生产环境中的行为,并让bug仅在测试环境中表现出来而无声地保持休眠状态。 我们不需要额外的这类东西来使我们的测试更具风险。

摘要

编程和测试还有更多方面。 本文仅讨论讨论中出现的一小部分特定问题。 文章中还列出了一些重要的经验教训:

  • 测试被测系统(SUT),而不是依赖项。 注意,实际上在测试某些依赖项的功能时,您可能会认为您正在测试SUT。 使用愚蠢而简单的模拟。
  • 遵循TDD。 编写测试之前并与功能开发混在一起。 如果不只是因为您不这样做而已,那么至少在编写代码之前和同时考虑一下测试。 可测试的代码通常更好(不仅仅是测试)。
  • 考虑一下其他程序员将如何使用您的代码。 想象一下,一个普通的程序员如何使用您的API并不仅为像您这样的天才产生代码的接口,他们比您更了解您的意图。
  • 大三的时候,不要仅仅因为可以就去寻求理想的解决方案。 使用无聊且简单的解决方案。 您将知道您何时是大四学生:什么时候不再想用无聊的解决方案了。

翻译自: https://www.javacodegeeks.com/2019/07/inject-able-only-test.html

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

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

相关文章

E1倒换保护设备知识详解

E1倒换是一款针对于国内重要部门而开发的保护设备,针对某些重要用户要求,E1倒换设备除了可以满足主、备两个传输路由间无损伤自动切换外,还可以满足主、备用户设备间自动切换。那么,什么是E1倒换,E1倒换保护怎么分类&a…

E1 PCM复用设备常见故障及处理方法

目前国内PCM设备技术发展非常迅速,PCM设备在通信系统中也是使用最多最常用到的。但是不少用户在使用PCM设备时会遇到各种故障,那么,我们该如何解决呢?接下来就由飞畅科技的小编来为大家介绍下E1 PCM复用设备常见故障及处理方法。 …

jooq中record_在Spring中使用jOOQ:CRUD

jooq中recordjOOQ是一个库,可帮助我们重新控制SQL。 它可以从我们的数据库生成代码,并允许我们使用其流畅的API来构建类型安全的数据库查询。 本教程前面的部分向我们介绍了如何配置示例应用程序的应用程序上下文以及如何从数据库中生成代码。 现在&am…

E1 PCM复用设备作用

Pulse Code Modulation(PCM),中文称脉码调制或PCM复用设备,PCM复用设备的目的就是使交换机之间一条中继线不是只传送一条电话信号。 PCM复用设备也就是将语音,数据信号复接成2M信号的设备,直白一点就是将如…

变色龙功能

在《神秘博士》中,卡梅利恩(Kamelion)角色是可以采取任何形式的机器人。 据称,他们使用的物理道具非常麻烦,只有其创建者才能理解,而该创建者并没有帮助纠正它。 因此,Chamelion功能... 考虑以…

E1常见问题介绍

1. E1与CE1是由谁控制,电信还是互连的两侧的用户设备?用户侧肯定要求支持他们,电信又是如何分别实现的? 答:首先由电信决定,电信可提供E1和CE1两种线路,但一般用户的E1线路都是CE1,除非你特别要…

MSTP多业务传输平台对设备接口的要求有哪些?

MSTP(Multi-Service Transfer Platform)(基于SDH 的多业务传送平台)是指基于SDH 平台同时实现TDM、ATM、以太网等业务的接入、处理和传送,提供统一网管的多业务节点。 MSTP的实现基础是充分利用SDH技术对传输业务数据…

jibx_Jibx Jersey2集成

jibxJersey2为Jackson和JAXB提供内置支持。 但是默认情况下不支持Jibx。 要将Jibx与Jersey2结合使用,我们将XML输入作为流,并在接收到请求之后,使用Jibx对其进行解析。 但是实际上,有更好的方法可以使用MessageBodyReader和Messag…

PCM复用设备的安装和使用注意事项

PCM设备在通信系统中的是一种很常用的设备,但是不少用户在购买了PCM设备后,都不懂怎么去安装使用PCM复用设备。下面,飞畅科技的小编来为大家详细介绍下PCM复用设备的安装和使用注意事项,一起来看看吧! PCM复用设备的安…

PCM复用设备功能介绍

PCM设备功能主要分为四大部分:接入与复用、时隙交叉、2M线路保护、接口测试功能。接下来就由飞畅科技的小编来为大家详细介绍下PCM复用设备的功能,一起来看看吧! PCM复用功能: 用户业务接入与复用是PCM设备最基本的功能&#xff…

对象和索引流

我本来要写一篇关于如何将流与每个元素的索引混合的文章,但是Baeldung上的人们已经很好地涵盖了这个主题 ! 鉴于我是他们编辑团队的一员,我为他们/我们感到自豪。 有趣的是,特别是Streams中的Java函数式编程如何使我们脱离了一些…

PCM复用设备主要传输什么业务?

PCM即脉冲编码调制,在通信系统中完成将语音信号数字化功能。PCM的实现主要包括三个步骤完成:抽样、量化、编码。分别完成时间上离散、幅度上离散、及量化信号的二进制表示。 1、 抽样:所谓抽样,就是对模拟信号进行周期性扫描&…

Pcm设备2M通道,E1的基础知识介绍

Pcm设备2M通道在业内常简述为E1,E1这个词在通信行业起着非常重要的作用,相信刚接触这个词的人必定会感到陌生。接下来就由飞畅科技的小编来为您详细的介绍一下E1的基础知识。 一、E1概述 E1是ITU-T制定并由欧洲邮政与电信协会(CEPT&#xff…

数据结构栈的知识_数据知识栈

数据结构栈的知识并发不适合胆小者 我们都知道并发编程很难正确实现。 这就是为什么在执行线程任务之后要进行大量的设计和代码审查会议。 您永远不会将并发问题分配给经验不足的开发人员。 仔细分析问题空间,提出设计,并记录和审查解决方案。 这就是通…

PCM设备E1保护切换功能介绍

脉冲编码调制(PulseCodeModulation),简称PCM。是对连续变化的模拟信号进行抽样、量化和编码产生的数字信号。PCM的优点就是音质好,缺点就是体积大。PCM可以提供用户从2M到155M速率的数字数据专线业务,也可以提供话音、…

在Eclipse中使用Java 12

1.安装JDK 12 链接: https : //www.oracle.com/technetwork/java/javase/downloads/jdk12-downloads-5295953.html 2.安装Eclipse 4.11 链接: https : //download.eclipse.org/eclipse/downloads/drops4/R-4.11-201903070500 …

PCM设备的作用,为什么要选用PCM设备?

PCM设备在通信系统中是利用E1(2M)线路进行传输多种业务数据的基群设备。但是不少用户在开始使用之前,并不能确定PCM能否满足他的需求,也不清楚有PCM这样的一个名词。接下来飞畅科技的小编来为大家介绍下PCM设备的作用,…

RS485光纤中继器有哪些优缺点?

信号在传输过程中会不断衰减,为了不让信号衰减对通信产生影响,产生了中继器。仅做放大信号用,把信号传导偏远的地方。 中继器又被称为转换器或放大器,执行物理层协议,负责第一层(物理层)的数据中…

intellij注释模板_IntelliJ中的实时模板

intellij注释模板如上所述这里 ,的IntelliJ的现场模板可以让你轻松地插入预定义的代码片段到你的源代码。 我在下面发布了一些我最常用的模板,链接到我在GitHub上的模板文件的完整列表(作为设置新IntelliJ环境时的参考)&#xff…

485转换器产品功能特点及技术参数介绍

485转换器主要的作用是将单端的RS-232信号转换为平衡差分的RS-485或RS-422信号。RS-485、RS-422自动识别功能,使用更加简单。接下来就由飞畅科技的小编来为大家详细介绍下485转换器的产品功能特点及技术参数,一起来看看吧! 485转换器产品特点…