sql 注射_只能在测试中注射吗?

sql 注射

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

问题简介

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

使它可测试:注入模拟

如何使此代码可测试?

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

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

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

可测试的好吗?

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

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

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

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

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

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

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

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

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

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

责任

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

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

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

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

您基本上有三个选择:

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

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

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

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

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

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

防止生产注入

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

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

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

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

为什么我偏爱第一个解决方案?

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

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

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

摘要

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

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

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

sql 注射

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

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

相关文章

IntelliJ IDEA查看方法在哪里被调用(Method Usage Search/Method Call Hierarchy)

文章目录Usage SearchCall Hierarchy区别Usage Search 搜索使用的地方,快捷键如下: 你可以把光标移到方法名称处,然后点击右键,找到 Find Usages 菜单项,意思是“找到使用它的地方”。 例如我要查看哪些地方调用 f…

java编程学习方法_在线学习Java编程的最佳方法

java编程学习方法1.简介 Java是使用最广泛的编程语言之一。 根据Github的最新报告 ,Java被列为仅次于JavaScript的第二大最常用的编程语言。 掌握Java的人有很多话题。 好消息是,您可以在线找到很多内容。 在这篇文章中,我们将对所有这些主题…

hibernate 标识符_Hibernate中的标识符

hibernate 标识符Hibernate中的标识符为实体的主键属性建模。 它有助于我们唯一地标识JPA实体。 每个实体都必须定义一个标识符。 同样,它可以是简单的也可以是复合的。 我们可以通过几种方式定义一个Hibernate标识符。 在本教程中,我们将学习如何做。 …

java中延迟_Java中的延迟分配

java中延迟程序员本质上是懒惰的,而similis simili gaudet就像程序是懒惰的一样。 您听说过延迟加载吗? 还是懒惰的单身人士? (不过,我个人更喜欢单一麦芽版本。)如果使用Scala或Kotlin(这也是一…

camel apache_短款Apache Camel K

camel apache您可能已经看到我们在Camel K周围的Apache Camel社区中所做的工作。 Nicola于半年前在他的博客中介绍了Camel K , 就在几个月前,我们正在讨论一个新项目,该项目可以作为Apache Camel的一部分启动。 一个有可能改变人们处理集成方…

java 栈 队列 接口_Java队列接口

java 栈 队列 接口介绍: 队列是FIFO(先进先出)抽象数据类型(ADT)。 换句话说,按插入顺序将元素删除。 java.util.Queue是Java 中的接口,并且从java.util.Collection扩展。 一些常用的Queue实现…

jakarta ee_Jakarta EE 8状态

jakarta ee遵循Jakarta EE的人们可能知道即将发布的Jakarta EE 8在功能上将与Java EE 8等效。其原因是我们想证明从Oracle的传输已经完成,并且我们能够产生这些流程,规范,测试套件以及通过Eclipse Foundation的兼容实现。 到目前为止&#x…

IntelliJ IDEA如何查看接口的实现类以及如何查看被实现的接口

在接口的左边有个向下的小箭头,点击小箭头就能看到接口的实现类和方法的实现: 在实现类的左边有个向上的小箭头,可以查看被实现的接口和被覆盖重写的方法:

c#自定义控件资源释放问题_定义资源

c#自定义控件资源释放问题在Fielding的论文中 ,资源描述为: “可以命名的任何信息”……“文档或图像,临时服务(例如,“洛杉矶今天的天气”),其他资源的集合,非虚拟对象&#xff08…

MySQL数据库存入日期(java.sql.Date)数据,天数会少一天的问题

网络上给的解决办法: 这是数据库服务器时区的问题,即连接参数 serverTimezone 的问题,默认情况下 serverTimezoneUTC,改成 HongKong 或者 Asia/Shanghai 就可以了。如下所示: jdbc:mysql://localhost:3306/test?useU…

spring的bean范围_Spring Bean范围

spring的bean范围介绍: Spring核心容器实例化bean并管理其生命周期。 在定义bean时,我们可以提供其范围。 除非明确提供,否则单例是Spring容器中Bean的默认范围。 Spring提供了五种类型的bean作用域。 在本教程中,我们将探讨它们…

java.util.Date转换成java.sql.Date

// 获取当前的系统时间,以java.util.Date对象返回 Date dateUtil new Date(); // 获取当前的系统时间,以时间戳返回 long l System.currentTimeMillis();时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现…

省编码市编码区县编码_无浪费编码

省编码市编码区县编码本文介绍了如何通过减少软件堆栈中的浪费来高效解决有意义的事件处理问题。 Java通常被视为无法在低内存环境中有效运行的内存猪。 目的是证明许多人认为不可能的事情,有意义的java程序几乎可以在没有内存的情况下运行。 示例流程 在Java的单…

Java日期时间字符串和毫秒相互转换的方法

参考链接: 1.https://www.jb51.net/article/130195.htm 2.https://blog.csdn.net/yhj19920417/article/details/73799842?locationNum10&fps1

谷歌本地不支持websocket_django开发-websocket的实现

今天介绍下如何在django中使用channels实现websocket。其实还可以使用dwebsocket实现websocket,这里不做介绍。首先介绍一个概念ASGI。ASGI异步网关协议接口,一个介于网络协议服务和Python应用之间的标准接口,能够处理多种通用的协议类型&…

我要正式开始《一个项目征服Java中高级体系》

在互联网上经常看到很多人说35岁危机的问题、大厂裁员、互联网寒冬这些问题。我感觉比较幸运的是,在之前大环境还不是很坏时候就被裁了一次,所以我很早就开始做持续的准备,现在不好说一定能怎么样, 至少自己在持续的探索适合自己的…

cuba 平台_CUBA 7的新功能

cuba 平台三年前,我们宣布了该框架的第二个公开可用的主要版本。 CUBA 6是改变游戏规则的版本–许可从专有转为Apache 2.0。 那些日子,我们甚至无法猜测从长远来看它将把框架带到哪里。 CUBA社区开始呈指数级增长,因此我们了解了开发人员如何…

java.util.Date详解

获取当前的系统时间: Date date new Date();获取毫秒数: long time date.getTime();毫秒数转成 Date 对象: long l 23434324324343L; Date date new Date(l);比较两个 Date 对象: SimpleDateFormat sdf new SimpleDateFo…

夸克代码_关于夸克的思考

夸克代码Quarkus,新的“超音速,亚原子” Java框架目前正受到广泛关注。 对于企业Java的未来而言,此构建和运行时工具背后的思想确实比我们感兴趣。 使用Quarkus有什么好处和缺点? 摆脱动力 Quarkus认为,在容器化的世…

ntdll 异常代码0xc0000374_不要把异常当做业务逻辑,这性能可能你无法承受

一:背景1. 讲故事在项目中摸爬滚打几年,应该或多或少的见过有人把异常当做业务逻辑处理的情况(┬_┬),比如说判断一个数字是否为整数,就想当然的用try catch包起来,再进行 int.Parse,如果抛异常就说明不是整…