[Java 开发实战] 💻 高级工程师的自我修养之单元测试(一):DAO 层测试

开篇导读

关于程序员而言,单元查验是非常重要的一项技术,但在许多实践的项目开发进程中,单元查验却往往被疏忽,这导致部分人也忽视其重要性,因此在开篇请容许笔者先唠叨几句关于它的重要性,若读者朋友对这部分内容现已了然于胸可直接前往 DAO 层查验 部分。

关于编写单元查验的一些基础知识,我在这篇 Java 单元查验 PPT 中有过介绍,本系列文章不再赘述,而旨java初学在解说在企业级项目中该怎样编写单元查验。

这个appointment系列计划编写三篇文章,DAO 层查验、事务逻辑层查验、高效编写查验。

为什么单元查验产品设计专业很重要?

为什么说判别一个程序员是中级还是高级,看看 TA 会不会写单元查验就知道了java面试题,由于写单元查验不仅是写查验代码,往往还需求从头审视产品代码自身,必要的时分需求进行重构才调继续编写查验,在编写单元查验代码的进程中时刻都能体会到高内聚、低耦合的编程思开源中国想。写单元查验,其实是为目java难学吗标模型添加了一个特别用户,这个进程也迫使咱们把方针模型开源软件规划的更加易用,总的说java怎样读来编写单元查验能够加深对高内聚、低耦合、面向接口编github直播平台永久回家程、依托注入、API 规划、单一职责等编程思维的掌握,所以单元查验是如此重要,以至于能够很好地用来判别一个工程师的技术水平,或许至少用产品批号是生产日期吗来判别其编程思维。

为什么单元查验难以实施?

appstore多小企业都难以实施单元查验,主要原因有:编写单元查验需求花费不少时刻、单元查验并非梦想中那样简略编写、开发人员对单元查验github敞开私库的了解不行全面等。还有一些更糟糕的状况,比如代码自身完结度不行,CRUD 功用背面短少数据验证、服务端事务逻辑验证,系统自身就一触即溃,若要编写单元查验,需求做许多的代码改造作业,这种状况我愿称之为单元查验领域的「戴维斯双杀」效应——由于代码自身完结度低,本来完善的代码应当具有必定的杂乱度,但在开发时却完结的极为简略,只满意了外表的功用,开发人员以为过于简略的代码没有编写github敞开私库单元查验的必要,导致产品代码Java质量下滑、对单元查验的了解歪曲的双重负循环。

单元查验难以实施,总的能够归结为开发才调产品司理和产品质量文明的原因github打不开,关于想长时刻开展的企业产品艺术设计专业来说,无疑是会github中文社区重视这两个方面产品战略,因此大多数企业也在不断打败这些问题,进步工程师的才调,加强编写单元查验的质量和功率,一起还要建立正确的产品质量观念,要知道即使是付出了额外的编写单元查验的时刻,总的时刻本钱也并不会添加,由于「质量是免费的」,产品质量进步了,用于排查问题、批改 bu开源阅览g 的时刻天然变少了。

在企业中注入产品质量产品艺术设计专业文明,进步开发人员编写单元查验的才调,只要做到这些,实施单元查验也没有梦想中困难。

单元查验根柢准则

首要要清楚单元查验的appetite一些根柢准则,优异的单元查验具有以下特点:

  • 产品质量法动的、可重复的
  • 简略完结
  • 一旦写好,将来都可运用
  • 任何人都可作业
  • 单击一个按钮就可作业
  • 能够快速地作业

单元查验并非是顺手写来验证功用的暂时代码,而是需求契合开源矿工 AIR 准则,所以编写起来是需求必定的功力的。

关于 AIR 准则在阿里的 Javajavaee 标准中有提及,其他相关的标准也值得学习,我在这里引证便当读者朋友查看,完好的标准可在 Github 中查看,地址:p3c 单元查验。

  1. 【强制java难学吗】好的单元查验有必要遵守AIR准则。

说明:单元检产品艺术设计专业验在线上作业时,感觉像产品艺术设计专业空气(AIR)相同并不存在,但在查验质量的确保上,却是非常要害的。好的单元查验宏观上来说,具有自动化、独立性、可重复实施的特点。

  • A:Automatic(自动化)
  • I:Independent(独立性)
  • R:Repeatable(可重复)
  1. 开源节流是什么意思是什么强制】单元查验应该是全自动实施的,并且非交互式的。查验用例一般是被守时实施的,实施进程有必要彻底自动化才有含义。输出作用需求人工查看的查验不是一个好的单元查验。产品运营单元查验中禁绝运用System.out来进行人肉验证,有必要运用assert来验证。

  2. 【强制】坚app是什么意思持单元检Java验的独立性。为了保appreciate证单元查验安稳牢靠且便于保护,单元查验用例之间决不能互相调用,开源矿工也不能依托实施的先后次序。

反例:methodappear2需求依托method1的实施,将实施作用作为me产品司理thod2的输入。

  1. 【强制】单元查验是能够重复实施的,不能遭到外界环境的影响。

说明:单元查验一般会被放到继续集成中,每次有代码check in时单元查验都会被实施。假定单测对外部环境(网络、服务、中间件等)有依托,简略导致继续集成机制的不行用。
正例:为了不受外界环境影响,要求规划代码时就把SUT的依托改成产品战略注入,在查验时用spring 这样的DI结构注入一个本地(内存)完结或许Mock完结。

  1. 【强制】关于单元查验,要确保查验粒度满意小,有助于精确定位问题。单测粒度至多是类级别,一般是办法级java怎样读别。

说明:只要查验粒度小才调在犯错时赶快定位到犯错方位。单测不担任查看跨类或许跨系统的交互逻辑,那是集成查验的领域。

  1. 【强制】中心事务、中心运用、中心模块的增量代码确保单元查验经过。

说明:新增代码及时补偿单元查验,假定新增代码GitHub影响了原有单元查验,请及时批改。

清楚这些根柢标准后,咱们来初步动手编写单元查验。

完善的单元查验,应该对项目的每一层级代码都进行查验,本篇文章咱们从 DAO 层初步。

DAO 层单元查验

DAO 层由于依托数据库,是比较难以查验的,这个章节将为你供给一些 DAO 层的查验办法。

以 MySQL 数APP据库为例,在作业 DAO 层的单元查验时,咱们不能依托外部的数据库,由于这会损坏 AIR 准则中的 I(独立性) 准则,要清除依托有几种办法:

  1. 运用嵌入式数据库java模拟器:h2、moby 等。
  2. 运用 Testcontainers 在 docker 中创建专为单元查验运用的数据库,实施完即销毁。java模拟器

运用嵌入式数据库

咱们先看第一种办法,以 h2 为例。

首要,在单元查验的运用装备 application.yml 中批改数据java难学吗源为 h2。

spring:
datasource:
drgithub是干什么的iver-class-name: org.h2.Driver
url: jd产品bc:h2:mem:ufo

假定咱们运用的是 JPA 进行开源是什么意思数据耐久化,装备这些即可,JPA 会在 h2 数据库中自动创建数据库。

若运用的是 MyBatis,则需求指定数据库的架构,添加以下装备,data 为数据初始javaapi中文在线看化脚本。

sp开源众包ring:
datasource:
schemgithub怎样下载文件a: classpath:db/schema-h2.sql
data: classpath:db/data-h2.sql

假定咱们的项目非常小,用这种办法就满意,但当数据库 schema 越来越庞大时,保护 sql 将变成一项耗开源代码网站github时的作业,那么咱们需求引进数据库的版别操控机制。

数据库版别操控

数据库版别操控能够运用 flyway 或许 liquibase,关于 liquibase 的用法,能够参看我写的 5 分钟搞定 liquibase 数据库版别操控 。

以 liquibase 为例,引进后,咱们在 application.yml 进行如下类似批改,单元查验作业时将首application要经过 liquibase 初始化数据库。

spring:
liquibaseAPP:
change-log: claapproachsspath:liquibase/master.xml
contexts: unigithub打不开t_tJavaest
enabled: true

留意,此时咱们编写的版别操控 sql 是为 MySQL 数据库预备的,若直接用于github官网 h2 数据库,大概率会出现兼容性问题,此时咱们有以下几个选开源阅览app下载安装择:

  1. 将用于 MySQL 的 sql 脚本稍作批改,用于 h2 数appreciate据库初始化。
  2. 运用 liqu产品批号是生产日期吗ibase 的 xml 语法来界说数据库结构,减少兼容性问题。
  3. 改用 Testcontai产品设计工作方向ners 辅佐查验。

前面两个挑选,都需求添加不小的作业量,咱们来看看运用 Testcontainers 会怎样。

运用 Testcontainers

Testcontgithub永久回家地址ainers 是一个支撑 JUnit 查验的开源库,能够运用 Docker 容器取得 即用即丢 数据库的才调Java

咱们跳过了其他选java怎样读项,直接挑选 Testcontainers,由于运用嵌入式数据库还有一些缺陷,比如 DAO 层运用了特定数据库才有的语法,那么单元查验根柢都无法经过,这在企业级项目中几乎是无法避免的,除非是特别独立单一的服务。

DAO 层单元查验不应该依托外部数据库,但在实施时也应当运用类出产的环境,这样的查验作用才更精确的。

运用 Testcontainers 并 不契合 AIR 准则,由于其依托了 Docker 环境,假定java初学在一台没有 Docker 环境的机器上作业,那么查验就会失利,其他它也不契合能够快速地作业这一点,究竟初始化 Docker 容器是需求必定的时刻的。

咱们看下怎样在代码中运用 Testcontainers 。

首要界说一个笼统的查验基类,具体的单元查验承继自该类,以下写法能够确保数据库只初始化一次。

@SpjavaeeringBootTest
@Co开源中国ntextConfiguration(initiajava怎样读lizers = Abstra产品生命周期ctUni产品战略tTest.DockerMySQjavaeeLDatjavascriptaSourceInitializer.cla开源代码网站githubss)
public abstract class AbstractUnitTest {
private static final MySQLContainer<?> mysql;
static {
mysql = new MySQLContainer&lt开源阅览app下载安装;>("my开源众包s产品设计ql:8.0.11")
.withDatabaseNagithub永久回家地址me("dbname");
mysql.start();
}
public static class DockerMyS开源QLDataSourceInitializer implements ApplicationContextInitializer<ConfigurableApplicagithub中文官网网页tionContext> {
@Override
public void initialize(@NotNull ConfigurableApplicationContext applicationContextjavascript) {
TestPropertySourceUtils.a产品设计专业ddInlinedPjava言语ropertiesToEnvironment(
applicationContext,
"spring.datasource.url=" + mysql.getJdbcUrl(),
"spring.datasource.userngithub是干什么的ame=" + mysql.getUsername(),
"spring.datasource.pjavaapi中文在线看assword=" + mysql.getPassword(),
"appearancespring.datasource.driver-class-name=" + mysql.getDriverClassName()
);
}
}
}

预备就绪后,在单元查验实施时将首要创建 Docker 容器,然后作业 liquibagithub怎样下载文件se 初始化数据库。

来看一个简略的 DAO 层查验的比如。

@SpringBootTes开源节流是什么意思是什么t
@RunWith(SpringRunner.class)
@TestInstance(TestInstance.L产品ifecy产品司理cle.PER_CLASS)
class NavSiteRepositoryTe开源节流是什么意思是什么st extends AbstractUnitTest {
@Autowire产品设计d
NavSiteRepository navSiteRepository;
@BeforeClass
void setUp() {
NavSite navSite = new NavSite();
navSitjava模拟器e.setSiteName("");
navSite.产品设计专业setSiteUrl("");
nav开源众包Site.setIco产品生命周期nPath("");
navSite.setSiteType(0);
navSite.setSort(github下载0);
navSijava模拟器te.setCreateTime(new Date());
navSite.setUpdateTime(nappstoreew Date());
navSiteRepository.save(navSite);
}
@Test
void findBySiteT产品设计ype_UnknownSiteType_ZeroSize产品艺术设计专业() {
List<NavSitjava言语e> navSites = navSiteRepository.findBySiteType(0);
assertThat(navSites.size()).isEqualTo(1);
}
@Test
voidjava初学 findBySitegithub官网Type() {
List<NavSite> navSites = navSit开源矿工eRepository.findBySiteType(0);
assertThat(navSites.size产品设计专业()).isEqualTo(1);
}
}

至此,咱们就完结了 JUnit5 + Testcontainergithub怎样下载文件s + Liquibase 进行 DAO 层查验。

方案取舍

应该在运用嵌入式数据库、Docker和专用查验数据库之间进行取舍,目前的继续集成环境中根柢都开源矿工有 Docker 环境,信赖 Testcon产品运营tainers 也会越来越盛行,就算不用在单元查验中,在 集成查验 中进行运用也是非常有用的github是干什么的一大利器。

总结如下:

  1. 在简略的产品批号是生产日期吗项目中运用 h2 或其他嵌入式数据开源库进行 DAO 层查验。
  2. 在特定的场景下挑选 Testcontainers,能够设法则开源众包其契合 AIR 准则并能快速作业,比如在开源阅览app下载安装 liquibase 项目中用于查验版别操控 sq产品艺术设计专业l 就是个不错的挑选。
  3. 集成查验中可尽管选用 Testcontajavaeein开源矿工erjava工作培训班s 。

写在最终

DAO 层的查验java难学吗难点主要在清除数据库这一外部依托上,java初学D产品批号是生产日期吗AO 层的事务逻辑代码较少,因此单元查验编写起来也比较简略,而杂乱app是什么意思的 Ser开源节流vice 层代码则不相同,产品批号是生产日期吗简略出现单元查验难以编写的状况,这时需求开源是什么意思优化代码规划,这部分内容咱们不才一篇 事务逻辑层查验 中胪陈。

发表评论

提供最优质的资源集合

立即查看 了解详情