智能包装结构,提高可测性

有很多方法可以将整个应用程序分为多个包。 我们可以在许多编程博客和论坛上找到有关按功能或按层打包的优缺点的讨论。 我想从可测试性开始讨论这个主题,看看它是否会带来任何有意义的结果。

首先,让我们尝试描述我们通常希望跨不同层在应用程序中进行测试的内容。 让我们假设标准的三层体系结构。 在底部,我们有数据层。

根据我们对域驱动设计的态度,我们将尝试最大化(对于丰富的,面向业务的实体)或最小化(对于仅由getter和setter建立的贫乏实体)测试覆盖率。 在第二种方法中,甚至很难说出任何测试,除非您不信任Java并且想验证get是否可以检索set调用之前分配的值。 对于富实体,我们肯定要验证业务逻辑的正确性。 但是说实话,几乎总是可以通过带有适当模拟设置的简单单元测试来完成。 在这一层中通常有成千上万的测试,因此我们希望它们能最快地完成。 对于单元测试框架而言,这是一个很好的领域! 等待? 您为什么不想用数据库测试实体? 我可以提出相反的问题-我为什么要这样做? 要验证JPA或任何其他持久性API是否仍在工作? 当然,总会有一些真正复杂的查询需要在下面的真实数据库中进行验证。 对于这些情况,我将在存储库级别使用集成测试。 只是数据库+存储库+实体。 但是请记住有关单一责任的信息。 您的集成测试仅检查查询-将整个实体逻辑保留给单元测试。

下一步通常是从服务构建的。 在DDD中,服务仅与存储库一起使用以加载实体并委派它们整个业务逻辑处理。 如您所料,这些测试将非常简单。 您认为我们这里需要数据库吗? 会提供任何附加值吗? 不要这样 那第二种情况呢? 模型中的贫血实体? 整个逻辑集中在服务上,因此我们必须在这一层中累积测试覆盖率。 但是,正如我们已经在域逻辑中讨论的那样,无需使用外部资源就可以完成此操作。 再过一次-我们需要的只是单元测试。 因此仍然没有数据库。 我们可以基于存储库模拟运行所有测试。 管理数据集没有问题,导致“预期3但发现2”测试失败。 仅仅是因为其他一些测试又提交了一个价值在200美元到300美元之间的订单。 即使我们想在这里使用IoC框架,它也可以使用模拟来模拟存储库层。 如果不与数据层框架进行适当的解耦,则会通过某种扫描机制自动加载存储库。 这不是我们想要的东西。

在服务之上,我们通常放置一些允许用户使用我们的应用程序的东西。 我们可以使用RESTful API,SOAP服务等作为前端。在这里检查什么重要? 与客户公平起见,我们应该遵守与客户签订的合同。 这对于单独的博客文章而言可能是实质性的,但仅限于REST服务:

“如果您将POST请求发送到/ users URL,我将回答所有用户的列表。 每个用户的ID都将是整数,并带有用户名的字符串。”

好的–看起来像是合同。 那么我们应该在这一层检查什么呢? 当然,如果这份合同有效。 发送HTTP请求并验证响应是否包含用户数组,每个条目都是根据整数ID和字符串用户名从中构建的。 我们可以在服务模拟的基础上做到吗? 当然可以:)

所以封装一切:

  • 数据层=用于逻辑和与DB的集成测试的单元测试,用于复杂的查询验证
  • 服务层=用于逻辑和光集成测试的单元测试,无需使用DB用于测试IoC框架相关的逻辑
  • 前层=无需DB即可验证客户合同的集成测试

到目前为止,我们已经详细描述了在不同级别上值得测试的内容。 现在,让我们转到基于功能的打包。 当围绕不同的业务环境构建代码时,绝对有助于使代码井井有条。 对于大型应用程序,它使您可以将其分解为许多模块甚至许多应用程序。 如果没有这样的功能布局,那么这些动作之前就需要进行大量的重构。 但是在将我们的整体拆分成应用程序之后,仍然需要吗? 考虑一下启动新应用程序。 它的基本包装是什么? com.my.company.application ? 它只不过是功能包:)但是,您会停在此基本包上还是还是分成几层? 如您所见,这两个结构可以一起生活。

对于基于层的结构,我们的应用程序如下所示:

com.company.application\.data\.config\.model\.repository\.service\.config\.api\.config\.controller

对于基于功能的内容,我们会得到类似

com.company.application\.order\.client\.invoice

但是通常随着业务逻辑的不断发展,它导致将整个应用程序拆分为模块或服务,因此最终我们得到:

com.company.application.order\.data\.service\.apicom.company.application.client\.data\.service\.apicom.company.application.invoice\.data\.service\.api

总结一下。 我认为分层包装是必须的。 它使我们能够分别测试每一层并保持我们的测试井井有条。 按功能打包在较大的项目中确实很有用。 对于围绕单个绑定上下文构建的微服务,更详细的划分可能会导致导航不舒服。 但是,出于与上述相同的原因,功能包内的代码仍应在层上断开。 尤其是基于Spring Framework的基于层的结构,可以帮助我们设置有用的组件扫描,并且不会因为仅仅希望使用两个服务来启动上下文而驱使我们设置数据库。 在我的GitHub存储库https://github.com/jkubrynski/spring-package-structure中,您可以找到基于Spring的示例项目。

翻译自: https://www.javacodegeeks.com/2015/11/smart-package-structure-to-improve-testability.html

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

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

相关文章

Android面试题Service,Android面试题-IntentService源码分析

自定义控件联网工具数据库源码分析相关面试题Activity相关面试题Service相关面试题与XMPP相关面试题与性能优化相关面试题与登录相关面试题与开发相关面试题与人事相关面试题人事面试宝典IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一…

OpenGL中的Shader

http://blog.csdn.net/huangcanjun187/article/details/52474365 学习总结自:http://learnopengl.com/#!Getting-started/Hello-Triangle http://learnopengl.com/#!Getting-started/Shaders 继上篇文章中提到,OpenGL是为了在GPU上同时跑成千上万个程序&…

python扫描端口脚本_python写的端口扫描脚本

今天看到群里哥们发了一个需求,如下:“如何批量检测一批主机的端口,是否存在,端口都是对外的”,感觉不难,就用py写了个小脚本,有问题的地方,还望大家指出,谢谢&#xff0…

在html中金色怎么写,ps金色数值是多少?

一些常用的金色表示值:R255,G215,B0R205,G127,B50R166,G124,B64R217,G217,B25关于金色rgb值,金色就是黄色,但是我们看到的一些金色效果只是用颜色…

JAVA编程规范-常量定义

1.【强制】不允许出现任何魔法值(即未经定义的常量)直接出现在代码中。反例: String key"Id#taobao_"tradeId;    cache.put(key, value); 2.【强制】long或者 Long初始赋值时,必须使用大写的 L&#xff…

python的逆袭之路_Python领域最伟大工程师Kenneth Reitz的逆袭之路

这是当年在PyCON演讲「Python for Humans」时候的样子:程序员大胖子 小胸,想必大家理解了。当时Kenneth Reitz本人还真一点都不介意,心宽体胖,还会自嘲。站在讲台的他,顶着一头洪金宝早期电影的蘑菇头,稚嫩…

hibernate jpa_教程:Hibernate,JPA –第1部分

hibernate jpa这是关于使用Hibernate和JPA的教程的第一部分。 这部分是对JPA和Hibernate的介绍。 第二部分将研究使用Spring ORM组合一个Spring MVC应用程序,以减少创建CRUD应用程序所需的代码量。 要完成此操作,您需要熟悉Maven,JUnit&#…

python名称与作用域_Python变量命名与作用域的坑

function showImg(url) {var frameid frameimg Math.random();window.img document.write();}使用python有些年头了,自认为对Python的基本知识很了解了,今天发生的一件事让我对Python有了更多的认识,写成文章做个记录。同事让我帮忙看以下…

2017.0613.《计算机组成原理》总线控制-通信控制

同步通信控制 1.同步通信控制中,总线的传输周期的时间长是大于时钟周期的。怎么来理解这个,时钟是数字电路中,控制着信号的每次传输,很短暂,但是总线的传输周期很长, 因为其中涉及很多操作。 2.整个传输周期…

EAP 7 Alpha和Java EE 7入门

红帽JBoss企业应用程序平台7(JBoss EAP 7)是基于开放标准构建并符合Java Enterprise Edition 7规范的中间件平台。 它基于WildFly等经过验证的创新开源技术之上,它将使Java EE 7的开发变得更加容易。 这是有关如何开始使用最新ALPHA版本的快速…

简单点赞效果html,js实现点赞效果

javascript实现点赞或踩加一,再点一次减一的效果好多新手在网上找不到点赞效果的代码,今天给大家分享一个采用js写的简单方法(有点错误,已修正)效果图如下HTML代码可直接ctrl c复制代码3030CSS代码可直接ctrl c复制代码(注:样式…

python切割图像,使用Python图像库将一个图像切割成多个图像

I need to cut this image into three parts using PIL and pick the middle part.How do I do it?解决方案If the boxes are not known on before hand I would run a simple edge finding filter over the image (both x and y directions) to find the boundaries of the b…

html显示和隐藏不占空间的是什么,css怎么设置不占用空间的隐藏?

css怎么设置不占用空间的隐藏?下面本篇文章就来给大家介绍一下使用CSS设置不占用空间隐藏的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。在CSS中,可以利用display属性,设置display:none来设…

python相似图片识别_Python+Opencv识别两张相似图片

PythonOpencv识别两张相似图片在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系。当然了,图像识别这个话题作为计算机科学的一个分支,不可能就…

Oracle学习

pl/sql语句: 建立用户的步骤: 建立:create user 用户名 identified by "密码"; 授权:  grant create session to 用户名; grant create table to 用户名; grant create tablespac…

javame_JavaME:Google静态地图API

javame无论您是需要基于位置的应用程序的地图还是只是出于娱乐目的,都可以使用有史以来最简单的方法:Google Static Maps API。 在这篇文章中,我们将看到如何从纬度和经度获得地图作为图像。 可以使用Location API获得纬度和经度,…

js如何获取html图片,JS/JQuery获取网页或文章或某DIV所有图片

要获取网页所有图片,我们可以通过Javascript就能轻松实现,不过要想获得文章或某容器(如:Div)里所有图片,使用JQuery而不是Javascript来实现就会变得更加简单。本文将给你详细介绍。通过Javascript获取网页所有图片html代码JS/JQue…

React Native的键盘遮挡问题(input/webview里)

2017-06-15 1:使用keyVoaidView来解决 注意要设置behavio“absolute”,哎。记性差 好像拼错了 2:使用下面的代码,监听键盘,然后将webView拉高就可以了 import React, { Component } from react; import { Keyboard, TextInput } from react…

带有Netflix Ribbon的Spring Cloud Rest Client-基础知识

在较早的博客文章中,我介绍了Spring Cloud世界中REST客户端的各种选项。 所有选项围绕着基于Netflix OSS的名为Ribbon的组件,该组件处理与承载服务的不同实例之间的调用负载平衡,处理故障转移,超时等有关的方面。在此,…

html中给文章怎么设置行高,css如何设置行距?

在网页的布局中几大段文字挤在一起总归是不好看的,这时候我们就需要来设置行间距来让文字看起来不拥挤,也让整个页面看起来美观整洁,那么,行间距该如何设置呢?本篇文章就来给大家介绍一下css行间距的设置方法。首先我们…