微服务架构之Spring Boot(六十二)

2022-05-23 15:40:15 浏览数 (1)

45.测试

Spring Boot提供了许多实用程序和注释来帮助您测试应用程序。测试支持由两个模块提供:spring-boot-test 包含核心

项, spring-boot-test-autoconfigure 支持测试的自动配置。

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

的库。

45.1测试范围依赖性

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

JUnit:单元测试Java应用程序的事实标准。

Spring测试和Spring Boot测试:Spring Boot应用程序的实用程序和集成测试支持。

AssertJ:一个流畅的断言库。

Hamcrest:匹配器对象库(也称为约束或谓词)。

Mockito:一个Java 模拟框架。

JSONassert:JSON的断言库。

JsonPath:JSON的XPath。

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

45.2测试Spring应用程序

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

对象而不是真正的依赖项。

通常,您需要超越单元测试并开始集成测试(使用Spring ApplicationContext )。能够在不需要部署应用程序或需要连接到其他基础架构的

情况下执行集成测试非常有用。

Spring框架包括用于此类集成测试的专用测试模块。您可以直接向 org.springframework:spring-test 声明依赖关系,或使

用 spring-boot-starter-test “Starter”将其传递给它。

如果您之前未使用过 spring-test 模块,则应首先阅读Spring框架参考文档的 相关部分。

45.3测试Spring Boot应用程序

Spring Boot应用程序是Spring ApplicationContext ,因此除了通常使用vanilla Spring上下文所做的测试之外,没有什么特别的要做。

仅当您使用 SpringApplication 创建外部属性,日志记录和Spring Boot的其他功能时,才会默认安装在上下文中。

Spring Boot提供了 @SpringBootTest 注释,当您需要Spring引导功能时,可以将其用作标准 spring-test @ContextConfiguration 注释

的替代。注释的工作原理是 通过 SpringApplication 创建测试中使用的 ApplicationContext 。除了 @SpringBootTest 之外,还提供了许多

其他注释来 测试应用程序的更具体的切片。

如果您使用的是JUnit 4,请不要忘记在测试中添加 @RunWith(SpringRunner.class) ,否则注释将被忽略。如果您正在使用

JUnit 5,则无需将等效的 @ExtendWith(SpringExtension) 添加为 @SpringBootTest ,而其他 @…Test 注释已经使用它进行注

释。

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

MOCK (默认):加载网络 ApplicationContext 并提供模拟网络环境。使用此批注时,不会启动嵌入式服务器。如果您的类路径上没有

Web环境,则此模式将透明地回退到创建常规非Web ApplicationContext 。它可以与 @AutoConfigureMockMvc

或 @AutoConfigureWebTestClient 一起用于基于模拟的Web应用程序测试。

RANDOM_PORT :加载 WebServerApplicationContext 并提供真实的网络环境。嵌入式服务器启动并在随机端口上侦听。

DEFINED_PORT :加载 WebServerApplicationContext 并提供真实的网络环境。嵌入式服务器启动并侦听定义的端口(来自您

的 application.properties )或默认端口 8080 。

NONE :使用 SpringApplication 加载 ApplicationContext 但不提供 任何网络环境(模拟或其他)。

如果您的测试是 @Transactional ,则默认情况下会在每个测试方法的末尾回滚事务。但是,当使用 RANDOM_PORT

或 DEFINED_PORT 的这种安排隐式地提供真正的servlet环境时,HTTP客户端和服务器在单独的线程中运行,因此在单独的事务中

运行。在这种情况下,在服务器上启动的任何事务都不会回滚。

如果您的应用程序使用不同的管理服务器端口, @SpringBootTest 和 webEnvironment = WebEnvironment.RANDOM_PORT 也将

在单独的随机端口上启动管理服务器。

45.3.1检测Web应用程序类型

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

上下文。

如果两者都存在,Spring MVC优先。如果要在此方案中测试响应式Web应用程序,则必须设置 spring.main.web-application-type 属性:

@RunWith(SpringRunner.class)

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

public class MyWebFluxTests { ... }

45.3.2检测测试配置

如果您熟悉Spring测试框架,则可能习惯使用 @ContextConfiguration(classes=… ) 来指定要加载的Spring @Configuration 。或者,您可

能经常在测试中使用嵌套的 @Configuration 类。

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

搜索算法从包含测试的包开始工作,直到找到使用 @SpringBootApplication 或 @SpringBootConfiguration 注释的类。只要您以合理的方式

构建代码,通常就会找到主要配置。

如果使用 测试批注来测试应用程序的更具体的片段,则应避免在main方法的应用程序类中添加特定于特定区域的配置设置 。

@SpringBootApplication 的基础组件扫描配置定义了排除过滤器,用于确保切片按预期工作。如果您

在 @SpringBootApplication - 带注释的类上使用明确的 @ComponentScan 指令,请注意这些过滤器将被禁用。如果您正在使用

切片,则应再次定义它们。

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

除了应用程序的主要配置之外,还使用嵌套的 @TestConfiguration 类。

Spring的测试框架在测试之间缓存应用程序上下文。因此,只要您的测试共享相同的配置(无论如何发现),加载上下文的潜在耗

时过程只发生一次。

45.3.3排除测试配置

如果您的应用程序使用组件扫描(例如,如果您使用 @SpringBootApplication 或 @ComponentScan ),您可能会发现仅为特定测试创建的顶

级配置类会意外地在任何地方进行检索。

如前所述, @TestConfiguration 可用于测试的内部类以自定义主要配置。前面所看到的,1941年{/}可以在一个内部类的测试的用于定制的主

配置。当放置在顶级类时, @TestConfiguration 表示不应通过扫描拾取 src/test/java 中的类。然后,您可以在需要的位置显式导入该类,

如以下示例所示:

@RunWith(SpringRunner.class)

@SpringBootTest

@Import(MyTestsConfiguration.class)

public class MyTests {

@Test

public void exampleTest() {

...

}

}

如果您直接使用 @ComponentScan (即不通过 @SpringBootApplication ),则需要使用 TypeExcludeFilter 注册。

0 人点赞