Springboot3.x配置类(Configuration)和单元测试

配置类在Spring Boot框架中扮演着关键角色,它使开发者能够利用Java代码定义Bean、设定属性及调整其他Spring相关设置,取代了早期版本中依赖的XML配置文件。

  • 集中化管理:借助@Configuration注解,Spring Boot让用户能在一个或几个配置类中统一管理所有配置信息。这种方式不仅简化了Bean的定义和配置,还提高了配置管理和维护的效率,避免了分散在多个XML文件中的复杂性。
  • 类型安全配置:由于配置工作是在Java代码内完成,因此可以充分利用Java编译时的类型检查机制,确保配置的准确性。这种做法有效防止了因拼写错误或配置不当引起的运行时错误,增强了应用程序的稳定性和可靠性。
  • 条件化配置能力:该框架还提供了基于条件的配置选项,允许根据特定条件(例如环境变量、系统属性等)动态决定是否创建或配置某个Bean。这项特性增加了应用部署的灵活性,使其更易于适应不同的运行环境和需求变化。
  • 自动装配(Autowiring)支持:Spring Boot内置的自动装配功能可以根据Bean的类型、名称或是限定符自动注入所需的依赖项。这大大减少了手动配置依赖关系的工作量,同时也降低了配置出错的风险。

示例代码

首先定义一个yml的配置文件

spring:application:name: demo-springbootjackson:time-zone: Asia/Shanghaidate-format: yyyy-MM-dd HH:mm:ssdefault-property-inclusion: non_null
server:port: 8888servlet:context-path: /api
logging:level:root: errorcom.coderlk: debug
app:config:upload-addr: /opt/uploadapp-key: 12345678

解析配置文件

下面的这个Bean映射到application.yml 中的app:config:xxx的配置

package com.coderlk.interceptor.demo.config;import lombok.Data;@Data
public class AppConfigProperties {private String uploadAddr;private String appKey;
}

UploadTools.java

package com.coderlk.interceptor.demo.config;import lombok.Data;
import lombok.extern.slf4j.Slf4j;@Data
@Slf4j
public class UploadTools {private AppConfigProperties appConfigProperties;public void upload() {log.info("app.config:{}", appConfigProperties);}
}

AppConfiguration.java

package com.coderlk.interceptor.demo.config;import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class AppConfiguration {@Value("${spring.application.name}")public String appName;@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}@Bean@ConfigurationProperties(prefix = "app.config")public AppConfigProperties appConfigProperties() {return new AppConfigProperties();}@Beanpublic AppConfigProperties appConfigPropertiesNon() {return new AppConfigProperties();}@Beanpublic UploadTools uploadTools(@Qualifier("appConfigProperties") AppConfigProperties properties) {UploadTools uploadTools = new UploadTools();uploadTools.setAppConfigProperties(properties);return uploadTools;}
}

关键点解析

  • @Configuration:标记该类是一个配置类,其中的方法可以用 @Bean 注解来定义Spring容器管理的bean。
  • **@Value("...")∗∗:用于将配置文件(如‘application.yml‘或‘application.properties‘)中的值注入到字段、构造函数参数或方法参数中。这里的‘...")∗∗:用于将配置文件(如‘application.yml‘或‘application.properties‘)中的值注入到字段、构造函数参数或方法参数中。这里的‘{spring.application.name}`是Spring Boot默认提供的属性之一,代表应用的名字。
  • @Bean:用来声明一个方法,其返回的对象应该被注册为Spring容器中的一个bean。每个@Bean方法实际上就是一种创建bean的方式。
  • @ConfigurationProperties(prefix = "app.config"):允许你将一组特定前缀的配置属性映射到一个Java对象上。这简化了从配置文件读取多个相关属性的过程。在这个例子中,所有以app.config开头的属性都会映射到AppConfigProperties对象中。
  • AppConfigProperties 和 UploadTools:是我们自定义的组件类,AppConfigProperties可能用于保存应用程序的配置属性,而UploadTools则可能是负责处理上传逻辑的组件,它依赖于AppConfigProperties来进行某些操作。

测试

请求体

GET http://localhost:8888/api/uploader
Token: 213coiu423m

控制台打印结果

INFO 13428 --- [interceptor-demo] [nio-8888-exec-5] c.c.interceptor.demo.config.UploadTools  : app.config:AppConfigProperties(uploadAddr=/opt/upload, appKey=12345678)

单元测试

Spring Boot 3 与 JUnit 5 的集成使得开发者可以方便地为他们的应用程序编写和运行单元测试及集成测试。以下是有关如何在 Spring Boot 3 中使用 JUnit 5 进行测试的一些关键点:

依赖管理

  1. 确保项目中包含相关依赖
  • 默认情况下,spring-boot-starter-test 依赖项已经包含了 JUnit 5 的支持,因此你通常不需要显式添加 JUnit 5 的依赖。
  • 如果你需要特定版本的 JUnit 5 或者有其他特殊需求,则可以在 pom.xml(对于 Maven 项目)或 build.gradle(对于 Gradle 项目)中添加相应的依赖。

<dependencies><!-- Spring Boot Starter Test(包含JUnit 5支持) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

编写测试

  1. 配置JUnit 5
  • Spring Boot 3 默认启用了 JUnit 5,因此只需按照 JUnit 5 的方式编写测试代码即可。你可以直接使用 @SpringBootTest 注解来加载 Spring Boot 应用程序上下文进行集成测试。

  1. 编写测试类
  • 创建一个简单的 JUnit 5 测试类,并使用 @SpringBootTest 加载整个应用上下文。
  • 使用 @Test@BeforeEach@AfterEach 等注解定义测试方法及其生命周期行为。


import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class MyApplicationTests {@Testvoid test() {// 这里写测试逻辑}
}

JUnit 5 新特性

  1. JUnit 5 新增特性
  • 注解:提供了如 @ParameterizedTest@RepeatedTest@DisplayName 等新注解。
  • 断言:JUnit 5 提供了更加强大的内置断言库,比如 Assertions.assertThat() 和假设条件 Assumptions.assumeThat()
  • 嵌套测试:通过 @Nested 注解实现更加结构化的测试组织,允许创建内部类来进行分组测试。
  • 扩展模型:可以通过 @ExtendWith 注解引入自定义扩展,从而增强测试功能。

例如,下面是一个使用了多个新特性的测试例子:

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.extension.ExtendWith;class StandardTests {@BeforeAllstatic void initAll() { /* 初始化 */ }@BeforeEachvoid init() { /* 每个测试前执行 */ }@DisplayName("成功的测试")@Testvoid succeedingTest() { /* 测试逻辑 */ }@Testvoid failingTest() {fail("一个失败的测试");}@Test@Disabled("为了演示目的禁用")void skippedTest() { /* 不会被执行 */ }@Testvoid abortedTest() {assumeTrue("abc".contains("Z"));fail("测试应该被终止");}@AfterEachvoid tearDown() { /* 每个测试后执行 */ }@AfterAllstatic void tearDownAll() { /* 清理工作 */ }@Nested@DisplayName("当栈是新的时候")class WhenNew {Stack<Object> stack;@BeforeEachvoid createNewStack() {stack = new Stack<>();}@Test@DisplayName("是空的")void isEmpty() {assertTrue(stack.isEmpty());}@Test@DisplayName("抛出异常时弹出")void throwsExceptionWhenPopped() {assertThrows(EmptyStackException.class, stack::pop);}}
}

综上所述,在 Spring Boot 3 中使用 JUnit 5 可以让你充分利用现代 Java 测试框架的优点,同时保持与 Spring 生态系统的紧密集成。这不仅简化了测试设置过程,还提高了测试代码的质量和可读性。

断言

JUnit 5 提供了一个丰富的断言库,允许开发者编写清晰、表达力强的测试用例。相比之前的版本,JUnit 5 的断言功能更为强大和灵活,支持多种类型的断言以适应不同的测试场景。以下是一些常用的 JUnit 5 断言方法及其使用示例:

基本断言

assertEquals(expected, actual):验证两个值是否相等。

assertTrue(condition) 和 assertFalse(condition):检查条件是否为真或假。

assertNull(object) 和 assertNotNull(object):检查对象是否为 null 或不为 null。

package com.coderlk.interceptor.demo;import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.*;public class UnitDemoTest {@Testvoid basicAssertions() {assertEquals(2 + 2, 4, "简单的加法");assertTrue("foo".startsWith("f"), "字符串开始于 'f'");assertNull(null, "值应该是null");}
}

集合和数组断言

@Test
void collectionAssertions() {String[] expected = {"a", "b", "c"};String[] actual = {"a", "b", "c"};assertArrayEquals(expected, actual, "数组应该相等");List<String> expectedList = Arrays.asList("apple", "banana", "orange");List<String> actualList = Arrays.asList("apple", "banana", "orange");assertIterableEquals(expectedList, actualList, "列表应该相等");
}

异常处理断言

  • assertThrows(exceptionClass, executable):用于验证代码块是否抛出了预期的异常。
@Test
void exceptionAssertions() {Exception exception = assertThrows(IllegalArgumentException.class, () -> {throw new IllegalArgumentException("一个非法参数异常");});assertEquals("一个非法参数异常", exception.getMessage());
}

超时断言

  • assertTimeout(timeout, executable):确保一段代码在指定时间内完成执行。
  • assertTimeoutPreemptively(Duration timeout, Executable executable):强制性地限制一段代码的执行时间,并在超时时立即终止执行。
@Test
void timeoutAssertions() {// 如果这段代码超过1秒,测试将失败assertTimeout(Duration.ofSeconds(1), () -> {// 执行一些操作...});// 使用 preemptive 超时策略,如果超时则立即中断执行assertTimeoutPreemptively(Duration.ofMillis(100), () -> {Thread.sleep(200); // 这个应该会导致超时异常});
}

组合断言

  • assertAll(Executable... executables):可以将多个断言组合在一起,在所有断言都通过的情况下才认为整个断言成功。如果任何一个断言失败,则整个测试失败。
@Test
void multipleAssertions() {assertAll(() -> assertEquals(2, 2),() -> assertTrue("hello".startsWith("he")),() -> assertFalse("test".isEmpty()));
}

条件断言

  • assumeTrue(boolean condition) 和 assumeFalse(boolean condition):假设条件成立或不成立,如果不满足假设条件,则跳过该测试。
@Test
void conditionalAssertions() {assumeTrue("abc".contains("a"));// 如果假设条件不满足,后面的代码不会被执行System.out.println("假设条件满足");
}

这些只是 JUnit 5 断言库的一部分功能。JUnit 5 的断言机制非常强大且灵活,能够帮助开发者更有效地进行单元测试和集成测试,确保应用程序的质量和可靠性。如果你需要更加复杂的断言逻辑,还可以考虑使用第三方库如 AssertJ 或 Hamcrest,它们提供了更加丰富的断言功能。

本课程学习代码,同步更新到

https://gitcode.com/fokman/springboot-demo.gitGitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。icon-default.png?t=O83Ahttps://gitcode.com/fokman/springboot-demo.git

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

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

相关文章

鸿道Intewell-C纯实时构型,适合有功能安全认证需求的工业操作系统

鸿道Intewell-C纯实时构型&#xff0c;适合有功能安全认证需求的工业操作系统 鸿道Intewell-C是一款工业实时微内核操作系统&#xff0c;由科东软件自主研发&#xff0c;具有超低延迟和最小抖动&#xff0c;保障工业设备可以高效处理时间敏感的现场业务&#xff0c;支持多种工…

Stream– ESP8266物联网应用,(客户端向服务器发送数据信息 客户端向服务器请求数据信息)

Stream– ESP8266物联网应用 Stream对于ESP8266-Arduino语言来说指的是数据序列。请留意&#xff1a;在C编程中Stream常被翻译作“流”。我们认为将Stream称为数据序列更加直观。因为数据序列这一概念有两个很关键特点。 第一个特点是“序”&#xff0c;即数据序列不能是杂乱…

芯品荟|SWM221系列芯片之TFTLCD彩屏显示及控制

“革新未来&#xff0c;智驭控制新纪元”&#xff0c;由广东华芯微特集成电路有限公司市场总监张琢&#xff0c;对SWM221系列的强大功能表现进行了整体介绍。 确实&#xff0c;华芯微特在TFTLCD显示及控制有十多年应用基础和积累的团队&#xff0c;仍勇于挑战&#xff0c;自我…

MIT S6081 2024 Lab 1 | Operating System | Notes

目录 安装与下载 实验1 开始我们的实验 sleep&#xff08;简单&#xff09; pingpong&#xff08;简单&#xff09; primes (中等)/(困难) find&#xff08;中等&#xff09; xargs&#xff08;中等&#xff09; finally Reference I. Tools Debian 或 Ubuntu Arch…

华为认证HCIA——数据传输形式,数据封装的基本概念

前言&#xff1a; 整理下学习笔记&#xff0c;打好基础&#xff0c;daydayup!!! 对网络概念有基本理解后&#xff08;华为认证HCIA——网络基本概念&#xff09;&#xff0c;开始进一步学习数据传输。 数据传输的形式 数据传输主要有三种形式&#xff1a; 1&#xff0c;电路传…

opencv小练习(未完成版)

读取一张彩色图像并将其转换为灰度图。 import cv2# 读取图片 img cv2.imread("./duck.png") img cv2.resize(img, dsizeNone, fx0.4, fy0.4, interpolationcv2.INTER_LINEAR) # 读取一张灰度图 img_gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 展示图片 cv2.im…

WSL (Windows Subsystem for Linux)

文章目录 Windows下使用Linux的三种方式&#xff1a;1.WSL(1)安装WSL(2)初始化Linux系统(3)安装、创建、激活 Python虚拟环境 2.虚拟机3.Docker Windows下使用Linux的三种方式&#xff1a; 1.WSL 是最简单的在 Windows 上运行 Linux 环境的方式&#xff0c;适用于日常开发和命…

金融分析-Transformer模型(基础理论)

Transformer模型 1.基本原理 transformer的core是注意力机制&#xff0c;其本质就是编码器-解码器。他可以通过多个编码器进行编码&#xff0c;再把编码完的结果输出给解码器进行解码&#xff0c;然后得到最终的output。 1.1编码器 数据在编码器中会经过一个self-attention的…

【一本通】两个数的最小公倍数

【一本通】两个数的最小公倍数 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输入两个正整数&#xff0c;编程计算两个数的最小公倍数。 输入 两个整数 输出 最小公倍数 样例输入 12 18样例输出 …

D 咖智能饮品机器人:开启商业新篇

在科技迅猛发展的当下&#xff0c;智能机器人正逐步渗透到各个商业领域&#xff0c;D 咖智能饮品机器人便是其中的佼佼者&#xff0c;它的出现为饮品行业带来全新的发展契机&#xff0c;有望开启商业新篇。 从大环境来看&#xff0c;消费者对于饮品的需求日益多元化和个性化。他…

35. Three.js案例-创建带阴影的球体与平面

35. Three.js案例-创建带阴影的球体与平面 实现效果 知识点 WebGLRenderer WebGLRenderer 是Three.js中用于渲染场景的主要类之一&#xff0c;它负责将场景中的对象渲染到画布上。 构造器 new THREE.WebGLRenderer(parameters : Object) 参数类型描述parametersObject可选…

leetcode212. 单词搜索 II

给定一个 m x n 二维字符网格 board 和一个单词&#xff08;字符串&#xff09;列表 words&#xff0c; 返回所有二维网格上的单词 。 单词必须按照字母顺序&#xff0c;通过 相邻的单元格 内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一…

容器化技术

文章目录 虚拟化容器容器隔离实现隔离文件 chroot隔离访问 namespace隔离资源 cgroups Dockerkubernetes 虚拟化容器 容器的首要目标是让软件分发部署过程从传统的发布安装包、靠人工部署转变为直接发布已经部署好的、包含整套运行环境的虚拟计划镜像。 一个计算机软件能够给正…

【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析

目录 一、前言 二、Spring Boot 简介 三、Spring Boot 核心模块 四、Spring Boot 项目实战&#xff1a;构建一个简单的 RESTful API 1. 创建 Spring Boot 项目 2. 配置数据库 3. 创建实体类 4. 创建 JPA 仓库接口 5. 创建服务层 6. 创建控制器层 7. 测试 API 8. 运…

土地档案管理关系[源码+文档]

目录 摘 要 Abstract 1 绪论 1.1 可行性研究编写目的 1.2 项目背景 1.3 土地管理现状 1.4 土地档案管理研究方向 1.5 项目目标 1.6 项目设计原则 1.6.1 实用性原则 1.6.2 经济性原则 1.6.3 合法性原则 2 相关技术介绍 2.1 三层架构的选择 2.2 编程…

使用C语言编写UDP循环接收并打印消息的程序

使用C语言编写UDP循环接收并打印消息的程序 前提条件程序概述伪代码C语言实现编译和运行C改进之自由设定端口注意事项在本文中,我们将展示如何使用C语言编写一个简单的UDP服务器程序,该程序将循环接收来自指定端口的UDP消息,并将接收到的消息打印到控制台。我们将使用POSIX套…

Audiocraft智能音频和音乐生成工具部署及使用

1、概述 Facebook开源了一款名为AudioCraft的AI音频和音乐生成工具。 该工具可以直接从文本描述和参考音乐生成高质量的音频和音乐。AudioCraft包含MusicGen、AudioGen和EnCodec三个模型&#xff0c;分别实现音乐生成、音频生成和自定义音频模型构建。 2、项目地址 https://…

vulnhub靶场【DriftingBlues】之7

前言 靶机&#xff1a;DriftingBlues-6&#xff0c;IP地址192.168.1.65 攻击&#xff1a;kali&#xff0c;IP地址192.168.1.16 都采用虚拟机&#xff0c;网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24 信息收集 使用nmap扫描端口 SSH服务&…

SCAU期末笔记 - Linux系统应用与开发教程样卷解析(2024版)

我真的不理解奥&#xff0c;为什么会有给样卷不自带解析的&#xff0c;对答案都没得对&#xff0c;故整理一篇 样卷1 一、选择题 1、为了遍历shell脚本调用时传入的参数&#xff0c;需要在shell脚本中使用_____。 A.$#表示参数的个数B.S表示所有参数C.$0表示脚本名D.$1表示…

spring\strust\springboot\isp前后端那些事儿

后端 一. 插入\更新一条数据&#xff08;老&#xff09; Map<String, Object> parameterMap MybatisUtil.initParameterSave("Send_ProjectFrozenLog", sendProjectFrozenLog); commonMapper.insert(parameterMap);parameterMap MybatisUtil.initParameter…