Spring Boot核心功能(二)

时间:2022-11-10 18:26:27

3. 简介

Spring Boot核心功能(二)

Spring Profiles 提供了一种分离应用程序配置部分并使其仅在某些环境中可用的方法。任何​​@Component​​​,​​@Configuration​​​或​​@ConfigurationProperties​​​可以在​​@Profile​​加载时标记为限制,如下例所示:

@Configuration(proxyBeanMethods = false)
@Profile("production")
public class ProductionConfiguration {

// ...

}

您可以使用​​spring.profiles.active​​​ ​​Environment​​​属性来指定哪些配置文件处于活动状态。您可以通过本章前面描述的任何方式指定属性。例如,您可以将它包含在您的​​application.properties​​中,如以下示例所示:

特性

spring.profiles.active=dev,hsqldb

您还可以使用以下开关在命令行上指定它:​​--spring.profiles.active=dev,hsqldb​​.

如果没有配置文件处于活动状态,则启用默认配置文件。默认配置文件的名称是​​default​​,并且可以使用该​​spring.profiles.default​​ ​​Environment​​属性进行调整,如以下示例所示:

特性

spring.profiles.default=none

​spring.profiles.active​​并且​​spring.profiles.default​​只能在非配置文件特定文档中使用。这意味着它们不能包含在配置文件特定文件或由.​​spring.config.activate.on-profile​

例如第二个文档配置无效:

特性

# this document is valid
spring.profiles.active=prod
#---
# this document is invalid
spring.config.activate.on-profile=prod
spring.profiles.active=metrics

3.1添加活动配置文件

该​​spring.profiles.active​​属性遵循与其他属性相同的排序规则:最高者​​PropertySource​​获胜。这意味着您可以在其中指定活动配置文件,​​application.properties​​然后使用命令行开关替换它们。

有时,将属性添加到活动配置文件而不是替换它们很有用。该属性可用于在由该属性​​spring.profiles.include​​激活的配置文件之上添加活动配置文件。入口点还有一个用于设置附加配置文件的 Java API ​​spring.profiles.active​​。​​SpringApplication​​请参阅SpringApplication​​setAdditionalProfiles()​​中的方法。

例如,当运行具有以下属性的应用程序时,即使使用 --spring.profiles.active 开关运行,也会激活公共和本地配置文件:

特性

spring.profiles.include[0]=common
spring.profiles.include[1]=local

如果给定的配置文件处于活动状态,则在下一节中描述的配置文件组也可用于添加活动配置文件。

3.2. 配置文件组

有时,您在应用程序中定义和使用的配置文件过于细化,使用起来很麻烦。例如,您可能拥有用于独立启用数据库和消息传递功能的配置文件​​proddb​​。​​prodmq​

为了帮助解决这个问题,Spring Boot 允许您定义配置文件组。配置文件组允许您为相关的配置文件组定义逻辑名称。

例如,我们可以创建一个​​production​​由我们的​​proddb​​和​​prodmq​​配置文件组成的组。

特性

spring.profiles.group.production[0]=proddb
spring.profiles.group.production[1]=prodmq

我们的应用程序现在可以启动,一​​--spring.profiles.active=production​​键激活​​production​​,​​proddb​​和​​prodmq​​配置文件。

3.3. 以编程方式设置配置文件

​SpringApplication.setAdditionalProfiles(…)​​您可以通过在应用程序运行之前调用来以编程方式设置活动配置文件。也可以使用 Spring 的​​ConfigurableEnvironment​​界面激活配置文件。

3.4. 配置文件特定的配置文件

​application.properties​​(或​​application.yml​​)和通过引用的文件的特定配置文件变体​​@ConfigurationProperties​​被视为文件并加载。有关详细信息,请参阅“配置文件特定文件”。

4. 记录

Spring Boot 使用Commons Logging进行所有内部日志记录,但保持底层日志实现打开。为Java Util Logging、Log4J2和Logback提供了默认配置。在每种情况下,记录器都预先配置为使用控制台输出,并且还提供可选的文件输出。

默认情况下,如果您使用“Starters”,则使用 Logback 进行日志记录。还包括适当的 Logback 路由,以确保使用 Java Util Logging、Commons Logging、Log4J 或 SLF4J 的依赖库都能正常工作。

4.1日志格式

Spring Boot 的默认日志输出类似于以下示例:

2022-10-20 12:40:11.311 INFO 16138 --- [main] osbdfsMyApplication:在 PID 16138 的 myhost 上使用 Java 1.8.0_345 启动 MyApplication(/opt/apps/myapp.jar 由 myuser 在 /opt/apps/ 中启动) 
2022-10-20 12:40:11.330 INFO 16138 --- [main] osbdfsMyApplication:未设置活动配置文件,回退到 1 个默认配置文件:“默认”
2022-10-20 12:40:13.056 INFO 16138 -- - [主] osbwembedded.tomcat.TomcatWebServer:Tomcat 使用端口初始化:8080 (http)
2022-10-20 12:40:13.070 INFO 16138 --- [主] o.apache.catalina.core.StandardService:启动服务 [Tomcat]
2022-10-20 12:40:13.070 INFO 16138 --- [main] org.apache.catalina.core.StandardEngine:启动 Servlet 引擎:[Apache Tomcat/9.0.68]
2022-10-20 12:40:13.178 INFO 16138 --- [main] oaccC[Tomcat].[localhost].[/]:初始化 Spring 嵌入式 WebApplicationContext
2022-10-20 12:40:13.178 INFO 16138 --- [main] wscServletWebServerApplicationContext:Root WebApplicationContext:初始化完成在 1762 毫秒
2022-10-20 12:40:13.840 INFO 16138 --- [main] osbwembedded.tomcat.TomcatWebServer:Tomcat 在端口:8080 (http) 上启动,上下文路径为 ''
2022-10-20 12 :40:13.850 INFO 16138 --- [main] osbdfsMyApplication:MyApplication 在 4.062 秒内启动(JVM 运行 5.452)

输出以下项目:

  • 日期和时间:毫秒精度,易于排序。
  • 日志级别:ERRORWARNINFODEBUGTRACE
  • 进程标识。
  • ​---​​用于区分实际日志消息开始的分隔符。
  • 线程名称:括在方括号中(可能会被截断以用于控制台输出)。
  • 记录器名称:这通常是源类名称(通常缩写)。
  • 日志消息。

4.2. 控制台输出

默认日志配置在写入时将消息回显到控制台。默认情况下,会记录​​ERROR​​-level、​​WARN​​-level 和​​INFO​​-level 消息。​​--debug​​您还可以通过使用标志启动应用程序来启用“调试”模式。

$ java -jar myapp.jar --debug

启用调试模式后,会配置一系列核心记录器(嵌入式容器、Hibernate 和 Spring Boot)以输出更多信息。启用调试模式不会您的应用程序配置为记录所有​​DEBUG​​级别的消息。

或者,您可以通过使用​​--trace​​标志(或​​trace=true​​在您的​​application.properties​​. 这样做可以为选择的核心记录器(嵌入式容器、Hibernate 模式生成和整个 Spring 产品组合)启用跟踪日志记录。

4.2.1颜色编码输出

如果您的终端支持 ANSI,则使用颜色输出来提高可读性。您可以设置​​spring.output.ansi.enabled​​为支持的值以覆盖自动检测。

使用​​%clr​​转换字配置颜色编码。在最简单的形式中,转换器根据日志级别为输出着色,如以下示例所示:

%clr(%5p)

下表描述了日志级别到颜色的映射:

等级

颜色

​FATAL​

红色的

​ERROR​

红色的

​WARN​

黄色

​INFO​

绿色的

​DEBUG​

绿色的

​TRACE​

绿色的

或者,您可以通过将其作为转换选项提供来指定应使用的颜色或样式。例如,要将文本变为黄色,请使用以下设置:

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}

支持以下颜色和样式:

  • ​blue​
  • ​cyan​
  • ​faint​
  • ​green​
  • ​magenta​
  • ​red​
  • ​yellow​

4.3. 文件输出

默认情况下,Spring Boot 仅记录到控制台,不写入日志文件。如果您想在控制台输出之外写入日志文件,您需要设置一个​​logging.file.name​​or​​logging.file.path​​属性(例如,在您的​​application.properties​​.

下表显示了如何​​logging.*​​一起使用这些属性:

表 5. 日志记录属性

​logging.file.name​

​logging.file.path​

例子

描述

(没有任何)

(没有任何)

仅控制台日志记录。

具体文件

(没有任何)

​my.log​

写入指定的日志文件。名称可以是确切的位置,也可以是相对于当前目录的位置。

(没有任何)

具体目录

​/var/log​

写入​​spring.log​​指定目录。名称可以是确切的位置,也可以是相对于当前目录的位置。

日志文件在达到 10 MB 时会旋转,并且与控制台输出一样,默认情况下会记录​​ERROR​​​-level、​​WARN​​​-level 和​​INFO​​-level 消息。

4.4. 文件轮换

​application.properties​​如果您使用的是 Logback,则可以使用您的or​​application.yaml​​文件微调日志轮换设置。对于所有其他日志记录系统,您需要自己直接配置轮换设置(例如,如果您使用 Log4J2,那么您可以添加一个​​log4j2.xml​​或​​log4j2-spring.xml​​文件)。

支持以下轮换策略属性:

姓名

描述

​logging.logback.rollingpolicy.file-name-pattern​

用于创建日志存档的文件名模式。

​logging.logback.rollingpolicy.clean-history-on-start​

如果应在应用程序启动时进行日志归档清理。

​logging.logback.rollingpolicy.max-file-size​

归档前日志文件的最大大小。

​logging.logback.rollingpolicy.total-size-cap​

在被删除之前可以占用的最大大小的日志档案。

​logging.logback.rollingpolicy.max-history​

要保留的存档日志文件的最大数量(默认为 7)。

4.5. 日志级别

所有受支持的日志记录系统都可以通过使用 TRACE、DEBUG、INFO、WARN、ERROR、FATAL 或 OFF 之一在 Spring 中设置记录器级别(例如​​Environment​​in ​​application.properties​​) 。记录器可以使用.​​logging.level.<logger-name>=<level>​​​​level​​​​root​​​​logging.level.root​

以下示例显示了潜在的日志记录设置​​application.properties​​:

特性

logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error

也可以使用环境变量设置日志记录级别。例如,​​LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG​​​将设置​​org.springframework.web​​​为​​DEBUG​​。

4.6. 日志组

能够将相关的记录器组合在一起通常很有用,以便可以同时配置它们。例如,您可能通常会更改所有与 Tomcat 相关的记录器的日志记录级别,但您不容易记住*包。

为了解决这个问题,Spring Boot 允许您在 Spring 中定义日志记录组​​Environment​​。例如,您可以通过以下方式定义“tomcat”组,方法是将其添加到您的​​application.properties​​:

特性

logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat

定义后,您可以使用一行更改组中所有记录器的级别:

特性

logging.level.tomcat=trace

Spring Boot 包括以下可开箱即用的预定义日志记录组:

姓名

记录器

网络

​org.springframework.core.codec​​​, ​​org.springframework.http​​​, ​​org.springframework.web​​​, ​​org.springframework.boot.actuate.endpoint.web​​​,​​org.springframework.boot.web.servlet.ServletContextInitializerBeans​

sql

​org.springframework.jdbc.core​​​, ​​org.hibernate.SQL​​​,​​org.jooq.tools.LoggerListener​

4.7. 使用日志关闭挂钩

为了在您的应用程序终止时释放日志记录资源,提供了一个关闭挂钩,该挂钩将在 JVM 退出时触发日志系统清理。除非您的应用程序部署为 war 文件,否则此关闭挂钩会自动注册。如果您的应用程序具有复杂的上下文层次结构,则关闭挂钩可能无法满足您的需求。如果没有,请禁用关闭挂钩并调查底层日志系统直接提供的选项。例如,Logback 提供上下文选择器,允许每个 Logger 在其自己的上下文中创建。您可以使用该​​logging.register-shutdown-hook​​属性来禁用关闭挂钩。将其设置为​​false​​将禁用注册。您可以在​​application.properties​​or​​application.yaml​​文件中设置属性:

特性

logging.register-shutdown-hook=false

4.8. 自定义日志配置

各种日志系统可以通过在类路径中包含适当的库来激活,并且可以通过在类路径的根目录或由以下 Spring​​Environment​​属性指定的位置提供合适的配置文件来进一步定制​​logging.config​​:

​org.springframework.boot.logging.LoggingSystem​​​您可以使用system 属性强制 Spring Boot 使用特定的日志记录系统。该值应该是实现的完全限定类名​​LoggingSystem​​​。您还可以使用​​none​​.

根据您的日志记录系统,将加载以下文件:

测井系统

定制

回溯

​logback-spring.xml​​​, ​​logback-spring.groovy​​​, ​​logback.xml​​​, 或​​logback.groovy​

日志4j2

​log4j2-spring.xml​​​或者​​log4j2.xml​

JDK(Java 实用程序日志记录)

​logging.properties​

为了帮助进行自定义,一些其他属性从 Spring 转移​​Environment​​到 System 属性,如下表所述:

春天环境

系统属性

注释

​logging.exception-conversion-word​

​LOG_EXCEPTION_CONVERSION_WORD​

记录异常时使用的转换字。

​logging.file.name​

​LOG_FILE​

如果已定义,它将在默认日志配置中使用。

​logging.file.path​

​LOG_PATH​

如果已定义,它将在默认日志配置中使用。

​logging.pattern.console​

​CONSOLE_LOG_PATTERN​

在控制台上使用的日志模式 (stdout)。

​logging.pattern.dateformat​

​LOG_DATEFORMAT_PATTERN​

日志日期格式的附加模式。

​logging.charset.console​

​CONSOLE_LOG_CHARSET​

用于控制台日志记录的字符集。

​logging.pattern.file​

​FILE_LOG_PATTERN​

在文件中使用的日志模式(如果​​LOG_FILE​​启用)。

​logging.charset.file​

​FILE_LOG_CHARSET​

用于文件日志记录的字符集(如果​​LOG_FILE​​启用)。

​logging.pattern.level​

​LOG_LEVEL_PATTERN​

呈现日志级别时使用的格式(默认​​%5p​​)。

​PID​

​PID​

当前进程 ID(如果可能且尚未定义为 OS 环境变量时发现)。

如果使用 Logback,还会传输以下属性:

春天环境

系统属性

注释

​logging.logback.rollingpolicy.file-name-pattern​

​LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN​

翻转日志文件名的模式(默认​​${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz​​)。

​logging.logback.rollingpolicy.clean-history-on-start​

​LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START​

是否在启动时清理归档日志文件。

​logging.logback.rollingpolicy.max-file-size​

​LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE​

最大日志文件大小。

​logging.logback.rollingpolicy.total-size-cap​

​LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP​

要保留的日志备份的总大小。

​logging.logback.rollingpolicy.max-history​

​LOGBACK_ROLLINGPOLICY_MAX_HISTORY​

要保留的存档日志文件的最大数量。

所有受支持的日志记录系统在解析其配置文件时都可以查阅系统属性。​​spring-boot.jar​​有关示例,请参见中的默认配置:

  • 回溯
  • 日志4j 2
  • Java 实用程序日志记录

4.9. Logback 扩展

Spring Boot 包含许多对 Logback 的扩展,可以帮助进行高级配置。您可以在​​logback-spring.xml​​配置文件中使用这些扩展。

ch.qos.logback.core.joran.spi.Interpreter@4 :71中的错误- [springProperty] 没有适用的操作,当前 ElementPath 是 [[configuration][springProperty]] ch.qos.logback.core.joran
中的错误.spi.Interpreter@4 :71 - [springProfile] 没有适用的操作,当前 ElementPath 是 [[configuration][springProfile]]

4.9.1配置文件特定的配置

该​​<springProfile>​​标签允许您根据活动的 Spring 配置文件选择性地包含或排除配置部分。元素内的任何位置都支持配置文件部分​​<configuration>​​。使用该​​name​​属性来指定哪个配置文件接受配置。标签可以包含配置​​<springProfile>​​文件名称(例如​​staging​​)或配置文件表达式。配置文件表达式允许表达更复杂的配置文件逻辑,例如​​production & (eu-central | eu-west)​​. 查看参考指南以获取更多详细信息。以下清单显示了三个示例配置文件:

<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

4.9.2. 环境属性

该​​<springProperty>​​标签允许您公开 Spring 中的属性​​Environment​​以在 Logback 中使用。​​application.properties​​如果您想在 Logback 配置中访问文件中的值,这样做会很有用。该标签的工作方式与 Logback 的标准​​<property>​​标签类似。​​value​​但是,您可以指定​​source​​属性的 (来自) ,而不是直接指定​​Environment​​。如果您需要将属性存储在范围以外的某个位置​​local​​,则可以使用该​​scope​​属性。如果您需要一个备用值(如果该属性未在 中设置​​Environment​​),您可以使用该​​defaultValue​​属性。以下示例显示了如何公开属性以在 Logback 中使用:

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}</remoteHost>
...
</appender>

5.国际化

Spring Boot 支持本地化消息,以便您的应用程序可以满足不同语言偏好的用户。默认情况下,Spring Boot​​messages​​在类路径的根目录中查找资源包的存在。

可以使用命名空间配置资源包的基本名称以及其他几个属性​​spring.messages​​,如下例所示:

特性

spring.messages.basename=messages,config.i18n.messages
spring.messages.fallback-to-system-locale=false

有关MessageSourceProperties更多支持的选项,请参阅。

6.JSON

Spring Boot 提供与三个 JSON 映射库的集成:

  • 格森
  • 杰克逊
  • JSON-B

Jackson 是首选的默认库。

6.1杰克逊

提供了 Jackson 的自动配置,并且 Jackson 是​​spring-boot-starter-json​​. 当 Jackson 在类路径上时,​​ObjectMapper​​会自动配置一个 bean。提供了几个配置属性用于自定义ObjectMapper.

6.1.1. 自定义序列化器和反序列化器

如果您使用 Jackson 来序列化和反序列化 JSON 数据,您可能需要编写自己的类​​JsonSerializer​​和​​JsonDeserializer​​类。自定义序列化程序通常通过模块向 Jackson 注册,但 Spring Boot 提供了一个替代​​@JsonComponent​​注解,可以更轻松地直接注册 Spring Bean。

您可以直接在或实现上使用​​@JsonComponent​​注释。您还可以在包含序列化器/反序列化器作为内部类的类上使用它,如以下示例所示:​​JsonSerializer​​​​JsonDeserializer​​​​KeyDeserializer​

@JsonComponent
public class MyJsonComponent {

public static class Serializer extends JsonSerializer<MyObject> {

@Override
public void serialize(MyObject value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {
jgen.writeStartObject();
jgen.writeStringField("name", value.getName());
jgen.writeNumberField("age", value.getAge());
jgen.writeEndObject();
}

}

public static class Deserializer extends JsonDeserializer<MyObject> {

@Override
public MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
ObjectCodec codec = jsonParser.getCodec();
JsonNode tree = codec.readTree(jsonParser);
String name = tree.get("name").textValue();
int age = tree.get("age").intValue();
return new MyObject(name, age);
}

}

}

中的所有​​@JsonComponent​​bean 都会​​ApplicationContext​​自动向 Jackson 注册。因为​​@JsonComponent​​是用 元注释的​​@Component​​,所以通常的组件扫描规则适用。

Spring Boot also provides JsonObjectSerializer and JsonObjectDeserializer base classes that provide useful alternatives to the standard Jackson versions when serializing objects. See JsonObjectSerializer and JsonObjectDeserializer in the Javadoc for details.

The example above can be rewritten to use ​​JsonObjectSerializer​​/​​JsonObjectDeserializer​​ as follows:

@JsonComponent
public class MyJsonComponent {

public static class Serializer extends JsonObjectSerializer<MyObject> {

@Override
protected void serializeObject(MyObject value, JsonGenerator jgen, SerializerProvider provider)
throws IOException {
jgen.writeStringField("name", value.getName());
jgen.writeNumberField("age", value.getAge());
}

}

public static class Deserializer extends JsonObjectDeserializer<MyObject> {

@Override
protected MyObject deserializeObject(JsonParser jsonParser, DeserializationContext context, ObjectCodec codec,
JsonNode tree) throws IOException {
String name = nullSafeValue(tree.get("name"), String.class);
int age = nullSafeValue(tree.get("age"), Integer.class);
return new MyObject(name, age);
}

}

}

6.1.2. 混合

Jackson 支持 mixins,可用于将其他注释混合到已在目标类上声明的注释中。Spring Boot 的 Jackson 自动配置将扫描您应用程序的包以查找带有注释的类,​​@JsonMixin​​并将它们注册到 auto-configured​​ObjectMapper​​中。注册由 Spring Boot 的​​JsonMixinModule​​.

6.2. 格森

提供了 Gson 的自动配置。当 Gson 在类路径上时,​​Gson​​会自动配置一个 bean。提供了几个​​spring.gson.*​​配置属性用于自定义配置。要进行更多控制,​​GsonBuilderCustomizer​​可以使用一个或多个 bean。

6.3. JSON-B

提供了 JSON-B 的自动配置。当 JSON-B API 和实现在类路径上时,​​Jsonb​​将自动配置一个 bean。首选的 JSON-B 实现是为其提供依赖管理的 Apache Johnzon。

7. 任务执行与调度

在上下文中没有​​Executor​​​bean 的情况下,Spring Boot 自动配置一个​​ThreadPoolTaskExecutor​​​合理的默认值,这些默认值可以自动关联到异步任务执行 ( ​​@EnableAsync​​) 和 Spring MVC 异步请求处理。

线程池使用8个核心线程,可以根据负载增长和收缩。这些默认设置可以使用命名空间进行微调​​spring.task.execution​​,如以下示例所示:

特性

spring.task.execution.pool.max-size=16
spring.task.execution.pool.queue-capacity=100
spring.task.execution.pool.keep-alive=10s

这将线程池更改为使用有界队列,以便当队列已满(100 个任务)时,线程池增加到最多 16 个线程。由于线程在空闲 10 秒(而不是默认情况下为 60 秒)时被回收,因此池的收缩更具侵略性。

​ThreadPoolTaskScheduler​​如果需要与计划的任务执行相关联(​​@EnableScheduling​​例如使用),也可以自动配置A。线程池默认使用一个线程,可以使用命名空间微调其设置​​spring.task.scheduling​​,如下例所示:

特性

spring.task.scheduling.thread-name-prefix=scheduling-
spring.task.scheduling.pool.size=2

如果需要创建自定义执行程序或调度程序,则​​TaskExecutorBuilder​​​bean 和bean 在上下文中都可用。​​TaskSchedulerBuilder​

8. 测试

Spring Boot 提供了许多实用程序和注释来帮助测试您的应用程序。测试支持由两个模块提供:​​spring-boot-test​​包含核心项目,并​​spring-boot-test-autoconfigure​​支持测试的自动配置。

大多数开发人员使用​​spring-boot-starter-test​​“Starter”,它导入 Spring Boot 测试模块以及 JUnit Jupiter、AssertJ、Hamcrest 和许多其他有用的库。

​hamcrest-core​​​被排除在外,赞成​​org.hamcrest:hamcrest​​​那是 的一部分​​spring-boot-starter-test​​。

8.1测试范围依赖

“ ​​spring-boot-starter-test​​Starter”(在 中​​test​​ ​​scope​​)包含以下提供的库:

  • JUnit 5:单元测试 Java 应用程序的事实标准。
  • Spring Test & Spring Boot Test:Spring Boot 应用程序的实用程序和集成测试支持。
  • AssertJ:一个流畅的断言库。
  • Hamcrest:匹配器对象库(也称为约束或谓词)。
  • Mockito:Java 模拟框架。
  • JSONassert : JSON 的断言库。
  • JsonPath:JSON 的 XPath。

我们通常发现这些通用库在编写测试时很有用。如果这些库不适合您的需求,您可以添加自己的其他测试依赖项。

8.2. 测试 Spring 应用程序

依赖注入的主要优点之一是它应该使您的代码更容易进行单元测试。您可以使用​​new​​运算符来实例化对象,甚至无需涉及 Spring。您还可以使用模拟对象而不是真正的依赖项。

通常,您需要超越单元测试并开始集成测试(使用 Spring ​​ApplicationContext​​)。能够执行集成测试而不需要部署您的应用程序或需要连接到其他基础设施是很有用的。

Spring 框架包括一个用于此类集成测试的专用测试模块。你可以直接声明一个依赖​​org.springframework:spring-test​​或者使用​​spring-boot-starter-test​​“Starter”来传递它。

如果您以前没有使用过该​​spring-test​​模块,则应首先阅读 Spring Framework 参考文档的相关部分。

8.3. 测试 Spring Boot 应用程序

Spring Boot 应用程序是 Spring ​​ApplicationContext​​,因此除了您通常使用普通 Spring 上下文执行的操作之外,无需进行任何特别的测试即可对其进行测试。

Spring Boot 提供了注解,当您需要 Spring Boot 特性时​​@SpringBootTest​​​,可以将其用作标准注解的替代方案。​​spring-test​ ​@ContextConfiguration​​​注释通过在您的测试中创建ApplicationContextSpringApplication使用的. 除了​​@SpringBootTest​​许多其他注释之外,还提供了用于测试应用程序更具体的切片。

默认情况下,​​@SpringBootTest​​​不会启动服务器。您可以使用 的​​webEnvironment​​​属性​​@SpringBootTest​​来进一步优化测试的运行方式:

  • ​MOCK​​(默认):加载网络ApplicationContext并提供模拟网络环境。使用此注释时不启动嵌入式服务器。如果您的类路径上没有可用的 Web 环境,则此模式会透明地回退到创建常规的 non-web ApplicationContext。它可以与您的 Web 应用程序结合使用@AutoConfigureMockMvc或@AutoConfigureWebTestClient用于基于模拟的测试。
  • ​RANDOM_PORT​​: 加载WebServerApplicationContext并提供一个真实的网络环境。嵌入式服务器启动并侦听随机端口。
  • ​DEFINED_PORT​​: 加载WebServerApplicationContext并提供一个真实的网络环境。嵌入式服务器启动并侦听定义的端口(来自您的application.properties)或8080.
  • ​NONE​​​​ApplicationContext​​:通过使用加载一个​​SpringApplication​​但不提供任何Web 环境(模拟或其他)。

8.3.1. 检测 Web 应用程序类型

如果 Spring MVC 可用,则配置常规的基于 MVC 的应用程序上下文。如果您只有 Spring WebFlux,我们将检测到它并配置一个基于 WebFlux 的应用程序上下文。

如果两者都存在,则 Spring MVC 优先。如果要在这种情况下测试响应式 Web 应用程序,则必须设置​​spring.main.web-application-type​​属性:

@SpringBootTest(properties = "spring.main.web-application-type=reactive")
class MyWebFluxTests {

// ...

}

8.3.2. 检测测试配置

如果您熟悉 Spring Test Framework,您可能习惯于使用​​@ContextConfiguration(classes=…)​​以指定​​@Configuration​​要加载的 Spring。或者,您可能经常​​@Configuration​​在测试中使用嵌套类。

在测试 Spring Boot 应用程序时,通常不需要这样做。​​@*Test​​只要您没有明确定义,Spring Boot 的注释就会自动搜索您的主要配置。

搜索算法从包含测试的包开始,直到找到一个用​​@SpringBootApplication​​​or注释的类​​@SpringBootConfiguration​​。只要您以合理的方式构建代码,通常会找到您的主要配置。

如果要自定义主要配置,可以使用嵌套​​@TestConfiguration​​​类。与将​​@Configuration​​​使用嵌套类代替应用程序的主要配置不同,嵌套​​@TestConfiguration​​类是在应用程序的主要配置之外使用的。

8.3.3. 排除测试配置

如果您的应用程序使用组件扫描(例如,如果您使用​​@SpringBootApplication​​or ​​@ComponentScan​​),您可能会发现仅为特定测试创建的*配置类意外地在各处被拾取。

正如我们之前看到的,​​@TestConfiguration​​可以在测试的内部类上使用来自定义主要配置。当放置在*类上时,​​@TestConfiguration​​表示​​src/test/java​​不应通过扫描获取其中的类。然后,您可以在需要的地方显式导入该类,如以下示例所示:

@SpringBootTest
@Import(MyTestsConfiguration.class)
class MyTests {

@Test
void exampleTest() {
// ...
}

}

8.3.4. 使用应用程序参数

如果您的应用程序需要arguments,您可以使用属性​​@SpringBootTest​​注入它们。​​args​

@SpringBootTest(args = "--app.test=one")
class MyApplicationArgumentTests {

@Test
void applicationArgumentsPopulated(@Autowired ApplicationArguments args) {
assertThat(args.getOptionNames()).containsOnly("app.test");
assertThat(args.getOptionValues("app.test")).containsOnly("one");
}

}

8.3.5使用模拟环境进行测试

默认情况下,​​@SpringBootTest​​不会启动服务器,而是设置一个模拟环境来测试 Web 端点。

使用 Spring MVC,我们可以使用MockMvcor查询我们的 Web 端点​​WebTestClient​​,如下例所示:

@SpringBootTest
@AutoConfigureMockMvc
class MyMockMvcTests {

@Test
void testWithMockMvc(@Autowired MockMvc mvc) throws Exception {
mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World"));
}

// If Spring WebFlux is on the classpath, you can drive MVC tests with a WebTestClient
@Test
void testWithWebTestClient(@Autowired WebTestClient webClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Hello World");
}

}

使用 Spring WebFlux 端点,您可以使用WebTestClient如下示例所示:

@SpringBootTest
@AutoConfigureWebTestClient
class MyMockWebTestClientTests {

@Test
void exampleTest(@Autowired WebTestClient webClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Hello World");
}

}

8.3.6. 使用正在运行的服务器进行测试

如果您需要启动一个完整运行的服务器,我们建议您使用随机端口。如果您使用​​@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)​​,则每次运行测试时都会随机选择一个可用端口。

​@LocalServerPort​​注释可用于将实际使用的端口注入到您的测试中。为方便起见,需要对启动的服务器进行 REST 调用的测试可以额外添加​​@Autowire​​一个WebTestClient,它解析到正在运行的服务器的相关链接,并带有用于验证响应的专用 API,如下例所示:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortWebTestClientTests {

@Test
void exampleTest(@Autowired WebTestClient webClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Hello World");
}

}

此设置需要​​spring-webflux​​​在类路径上。如果你不能或不会添加 webflux,Spring Boot 还提供了一个​​TestRestTemplate​​工具:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortTestRestTemplateTests {

@Test
void exampleTest(@Autowired TestRestTemplate restTemplate) {
String body = restTemplate.getForObject("/", String.class);
assertThat(body).isEqualTo("Hello World");
}

}

8.3.7. 自定义 WebTestClient

要自定义​​WebTestClient​​bean,请配置一个​​WebTestClientBuilderCustomizer​​bean。任何此类 bean 都​​WebTestClient.Builder​​使用用于创建​​WebTestClient​​.

8.3.8. 使用 JMX

由于测试上下文框架缓存了上下文,JMX 默认是禁用的,以防止相同的组件在同一个域上注册。如果此类测试需要访问​​MBeanServer​​,请考虑将其标记为脏:

@SpringBootTest(properties = "spring.jmx.enabled=true")
@DirtiesContext
class MyJmxTests {

@Autowired
private MBeanServer mBeanServer;

@Test
void exampleTest() {
assertThat(this.mBeanServer.getDomains()).contains("java.lang");
// ...
}

}

8.3.9使用指标

无论您的类路径如何,使用​​@SpringBootTest​​.

如果您需要在集成测试中将指标导出到不同的后端,请使用​​@AutoConfigureMetrics​​.

8.3.10模拟和窥探 Bean

运行测试时,有时需要在应用程序上下文中模拟某些组件。例如,您可能有一些在开发期间不可用的远程服务的外观。当您想要模拟在真实环境中可能难以触发的故障时,模拟也很有用。

Spring Boot 包含一个​​@MockBean​​​注解,可用于为您的​​ApplicationContext​​​. 您可以使用注解添加新 bean 或替换单个现有 bean 定义。注释可以直接用于测试类、测试中的字段或​​@Configuration​​类和字段。在字段上使用时,创建的模拟实例也会被注入。在每个测试方法之后,模拟 bean 都会自动重置。

以下示例将现有​​RemoteService​​bean 替换为模拟实现:

@SpringBootTest
class MyTests {

@Autowired
private Reverser reverser;

@MockBean
private RemoteService remoteService;

@Test
void exampleTest() {
given(this.remoteService.getValue()).willReturn("spring");
String reverse = this.reverser.getReverseValue(); // Calls injected RemoteService
assertThat(reverse).isEqualTo("gnirps");
}

}

此外,您可以使用​​@SpyBean​​​Mockito 包装任何现有的 bean ​​spy​​。

8.3.11自动配置的测试

Spring Boot 的自动配置系统适用于应用程序,但有时对于测试来说有点太多了。它通常有助于仅加载测试应用程序“切片”所需的配置部分。例如,您可能想要测试 Spring MVC 控制器是否正确映射 URL,并且您不想在这些测试中涉及数据库调用,或者您可能想要测试 JPA 实体,而当这些测试运行。

该​​spring-boot-test-autoconfigure​​​模块包含许多注释,可用于自动配置此类“切片”。它们中的每一个都以类似的方式工作,提供一个​​@…Test​​​可以加载的注释​​ApplicationContext​​​以及一个或多个​​@AutoConfigure…​​可用于自定义自动配置设置的注释。

8.3.12自动配置的 JSON 测试

要测试对象 JSON 序列化和反序列化是否按预期工作,您可以使用​​@JsonTest​​注释。 ​​@JsonTest​​自动配置可用的支持 JSON 映射器,它可以是以下库之一:

  • 杰克逊ObjectMapper,任何@JsonComponent豆子和任何杰克逊Module
  • ​Gson​
  • ​Jsonb​

如果需要配置自动配置的元素,可以使用​​@AutoConfigureJsonTesters​​注解。

Spring Boot 包括基于 AssertJ 的帮助程序,它们与 JSONAssert 和 JsonPath 库一起检查 JSON 是否按预期显示。、​​JacksonTester​​、​​GsonTester​​和类可分别用于 Jackson、Gson、Jsonb 和 Strings ​​JsonbTester​​。​​BasicJsonTester​​测试类上的任何辅助字段都可以​​@Autowired​​在使用​​@JsonTest​​. 以下示例显示了 Jackson 的测试类:

@JsonTest
class MyJsonTests {

@Autowired
private JacksonTester<VehicleDetails> json;

@Test
void serialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make").isEqualTo("Honda");
}

@Test
void deserialize() throws Exception {
String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
assertThat(this.json.parse(content)).isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}

}

如果您使用 Spring Boot 的基于 AssertJ 的帮助器对给定 JSON 路径中的数字值进行断言,则可能无法使用,​​isEqualTo​​​具体取决于类型。相反,您可以使用 AssertJ​​satisfies​​​断言该值与给定条件匹配。例如,以下示例断言实际数字是接近​​0.15​​​偏移量的浮点值​​0.01​​。

@Test
void someTest() throws Exception {
SomeObject value = new SomeObject(0.152f);
assertThat(this.json.write(value)).extractingJsonPathNumberValue("@.test.numberValue")
.satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));
}

8.3.13自动配置的 Spring MVC 测试

要测试 Spring MVC 控制器是否按预期工作,请使用​​@WebMvcTest​​注解。 ​​@WebMvcTest​​自动配置 Spring MVC 基础结构并将扫描的 bean 限制为​​@Controller​​, ​​@ControllerAdvice​​, ​​@JsonComponent​​, ​​Converter​​, ​​GenericConverter​​, ​​Filter​​, ​​HandlerInterceptor​​, ​​WebMvcConfigurer​​,​​WebMvcRegistrations​​和​​HandlerMethodArgumentResolver​​. 使用注解 时不会扫描常规​​@Component​​和bean。可用于包含bean。​​@ConfigurationProperties​​​​@WebMvcTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

通常,​​@WebMvcTest​​​仅限于单个控制器,并与 结合使用​​@MockBean​​,为所需的协作者提供模拟实现。

​@WebMvcTest​​​也自动配置​​MockMvc​​。Mock MVC 提供了一种强大的方法来快速测试 MVC 控制器,而无需启动完整的 HTTP 服务器。

@WebMvcTest(UserVehicleController.class)
class MyControllerTests {

@Autowired
private MockMvc mvc;

@MockBean
private UserVehicleService userVehicleService;

@Test
void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
}

}

如果您使用 HtmlUnit 和 Selenium,自动配置还提供 HtmlUnit ​​WebClient​​​bean 和/或 Selenium ​​WebDriver​​bean。以下示例使用 HtmlUnit:

@WebMvcTest(UserVehicleController.class)
class MyHtmlUnitTests {

@Autowired
private WebClient webClient;

@MockBean
private UserVehicleService userVehicleService;

@Test
void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot")).willReturn(new VehicleDetails("Honda", "Civic"));
HtmlPage page = this.webClient.getPage("/sboot/vehicle.html");
assertThat(page.getBody().getTextContent()).isEqualTo("Honda Civic");
}

}

如果类路径上有 Spring Security,​​@WebMvcTest​​​也会扫描​​WebSecurityConfigurer​​bean。您可以使用 Spring Security 的测试支持,而不是完全禁用此类测试的安全性。

8.3.14自动配置的 Spring WebFlux 测试

要测试Spring WebFlux控制器是否按预期工作,您可以使用​​@WebFluxTest​​​注释。 ​​@WebFluxTest​​​自动配置 Spring WebFlux 基础结构并将扫描的 bean 限制为​​@Controller​​​、​​@ControllerAdvice​​​、​​@JsonComponent​​​、​​Converter​​​、​​GenericConverter​​​、​​WebFilter​​​和​​WebFluxConfigurer​​​. 使用注解 时不会扫描常规​​@Component​​​和bean。可用于包含bean。​​@ConfigurationProperties​​​​@WebFluxTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

通常,​​@WebFluxTest​​​仅限于单个控制器并与​​@MockBean​​注释结合使用,为所需的协作者提供模拟实现。

​@WebFluxTest​​还有 auto-configures WebTestClient,它提供了一种强大的方法来快速测试 WebFlux 控制器,而无需启动完整的 HTTP 服务器。

@WebFluxTest(UserVehicleController.class)
class MyControllerTests {

@Autowired
private WebTestClient webClient;

@MockBean
private UserVehicleService userVehicleService;

@Test
void testExample() {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", "Civic"));
this.webClient.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN).exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("Honda Civic");
}

}

8.3.15自动配置的 Spring GraphQL 测试

Spring GraphQL 提供了专门的测试支持模块;您需要将其添加到您的项目中:

马文

<dependencies>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Unless already present in the compile scope -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

摇篮

dependencies {
testImplementation("org.springframework.graphql:spring-graphql-test")
// Unless already present in the implementation configuration
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
}

这个测试模块附带了GraphQlTester。测试仪在测试中大量使用,所以一定要熟悉使用它。有​​GraphQlTester​​变体,Spring Boot 将根据测试类型自动配置它们:

  • ExecutionGraphQlServiceTester服务器端执行测试,没有客户端也没有传输
  • 使用HttpGraphQlTester连接到服务器的客户端执行测试,有或没有实时服务器

Spring Boot 可帮助您使用注释测试Spring GraphQL 控制器​​@GraphQlTest​​。 ​​@GraphQlTest​​自动配置 Spring GraphQL 基础设施,不涉及任何传输或服务器。这会将扫描的bean 限制为​​@Controller​​、​​RuntimeWiringConfigurer​​、​​JsonComponent​​、​​Converter​​、​​GenericConverter​​、​​DataFetcherExceptionResolver​​和。使用注解 时不会扫描常规和bean。可用于包含bean。​​Instrumentation​​​​GraphQlSourceBuilderCustomizer​​​​@Component​​​​@ConfigurationProperties​​​​@GraphQlTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

通常,​​@GraphQlTest​​​仅限于一组控制器并与​​@MockBean​​注释结合使用,为所需的协作者提供模拟实现。

@GraphQlTest(GreetingController.class)
class GreetingControllerTests {

@Autowired
private GraphQlTester graphQlTester;

@Test
void shouldGreetWithSpecificName() {
this.graphQlTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Alice!");
}

@Test
void shouldGreetWithDefaultName() {
this.graphQlTester.document("{ greeting } ").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Spring!");
}

}

​@SpringBootTest​​测试是完整的集成测试,涉及整个应用程序。当使用随机或定义的端口时,会配置一个实时服务器并​​HttpGraphQlTester​​自动提供一个 bean,以便您可以使用它来测试您的服务器。配置 MOCK 环境后,您还可以​​HttpGraphQlTester​​通过使用以下命令注释测试类来请求 bean ​​@AutoConfigureHttpGraphQlTester​​:

@AutoConfigureHttpGraphQlTester
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class GraphQlIntegrationTests {

@Test
void shouldGreetWithSpecificName(@Autowired HttpGraphQlTester graphQlTester) {
HttpGraphQlTester authenticatedTester = graphQlTester.mutate()
.webTestClient(
(client) -> client.defaultHeaders((headers) -> headers.setBasicAuth("admin", "ilovespring")))
.build();
authenticatedTester.document("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class)
.isEqualTo("Hello, Alice!");
}

}

8.3.16自动配置的数据 Cassandra 测试

您可以使用它​​@DataCassandraTest​​来测试 Cassandra 应用程序。默认情况下,它配置一个​​CassandraTemplate​​,扫描​​@Table​​类,并配置 Spring Data Cassandra 存储库。使用注解 时不会扫描常规​​@Component​​和bean。可用于包含bean。(有关在 Spring Boot 中使用 Cassandra 的更多信息,请参阅“ data.html ”。)​​@ConfigurationProperties​​​​@DataCassandraTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

以下示例显示了在 Spring Boot 中使用 Cassandra 测试的典型设置:

@DataCassandraTest
class MyDataCassandraTests {

@Autowired
private SomeRepository repository;

}

8.3.17自动配置的 Data Couchbase 测试

您可以​​@DataCouchbaseTest​​用来测试 Couchbase 应用程序。默认情况下,它配置一个​​CouchbaseTemplate​​or ​​ReactiveCouchbaseTemplate​​,扫描​​@Document​​类,并配置 Spring Data Couchbase 存储库。使用注解 时不会扫描常规​​@Component​​和bean。可用于包含bean。(有关在 Spring Boot 中使用 Couchbase 的更多信息,请参阅本章前面的“ data.html ”。)​​@ConfigurationProperties​​​​@DataCouchbaseTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

以下示例显示了在 Spring Boot 中使用 Couchbase 测试的典型设置:

@DataCouchbaseTest
class MyDataCouchbaseTests {

@Autowired
private SomeRepository repository;

// ...

}

8.3.18。自动配置的数据 Elasticsearch 测试

您可以使用它​​@DataElasticsearchTest​​​来测试 Elasticsearch 应用程序。默认情况下,它配置一个​​ElasticsearchRestTemplate​​​,扫描​​@Document​​​类,并配置 Spring Data Elasticsearch 存储库。使用注解 时不会扫描常规​​@Component​​​和bean。可用于包含bean。(有关在 Spring Boot 中使用 Elasticsearch 的更多信息,请参阅本章前面的“ data.html ”。)​​@ConfigurationProperties​​​​@DataElasticsearchTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

以下示例显示了在 Spring Boot 中使用 Elasticsearch 测试的典型设置:

@DataElasticsearchTest
class MyDataElasticsearchTests {

@Autowired
private SomeRepository repository;

// ...

}

8.3.19自动配置的数据 JPA 测试

您可以使用​​@DataJpaTest​​注释来测试 JPA 应用程序。默认情况下,它会扫描​​@Entity​​类并配置 Spring Data JPA 存储库。如果类路径上有一个嵌入式数据库,它也会配置一个。默认情况下,通过将​​spring.jpa.show-sql​​属性设置为 来记录 SQL 查询​​true​​。这可以使用​​showSql()​​注释的属性来禁用。

使用注解 时不会扫描常规​​@Component​​​和bean。可用于包含bean。​​@ConfigurationProperties​​​​@DataJpaTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

默认情况下,数据 JPA 测试是事务性的,并在每个测试结束时回滚。有关更多详细信息,请参阅 Spring Framework 参考文档中的相关部分。如果这不是您想要的,您可以为测试或整个班级禁用事务管理,如下所示:

@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyNonTransactionalTests {

// ...

}

数据 JPA 测试也可以注入一个bean,它提供了一个专门为测试设计TestEntityManager的标准 JPA 的替代方案。​​EntityManager​

​JdbcTemplate​​​如果您需要,也可以使用A。以下示例显示了​​@DataJpaTest​​正在使用的注释:

@DataJpaTest
class MyRepositoryTests {

@Autowired
private TestEntityManager entityManager;

@Autowired
private UserRepository repository;

@Test
void testExample() {
this.entityManager.persist(new User("sboot", "1234"));
User user = this.repository.findByUsername("sboot");
assertThat(user.getUsername()).isEqualTo("sboot");
assertThat(user.getEmployeeNumber()).isEqualTo("1234");
}

}

内存嵌入式数据库通常适用于测试,因为它们速度快且不需要任何安装。但是,如果您更喜欢针对真实数据库运行测试,则可以使用​​@AutoConfigureTestDatabase​​注解,如以下示例所示:

@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
class MyRepositoryTests {

// ...

}

8.3.20自动配置的 JDBC 测试

​@JdbcTest​​​类似于​​@DataJpaTest​​​但适用于只需要 a​​DataSource​​​并且不使用 Spring Data JDBC 的测试。默认情况下,它配置一个内存嵌入式数据库和一个​​JdbcTemplate​​​. 使用注解 时不会扫描常规​​@Component​​​和bean。可用于包含bean。​​@ConfigurationProperties​​​​@JdbcTest​​​​@EnableConfigurationProperties​​​​@ConfigurationProperties​

默认情况下,JDBC 测试是事务性的,并在每次测试结束时回滚。有关更多详细信息,请参阅 Spring Framework 参考文档中的相关部分。如果这不是您想要的,您可以为测试或整个班级禁用事务管理,如下所示:

@JdbcTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class MyTransactionalTests {

}

如果您希望您的测试针对真实数据库运行,您可以使用与​​@AutoConfigureTestDatabase​​for 相同的方式使用注解​​DataJpaTest​​。