首页 Java java教程 开发/产品奇偶校验:Spring Boot Testcontainers

开发/产品奇偶校验:Spring Boot Testcontainers

Jan 10, 2025 am 11:03 AM

介绍

开发/产品平价旨在缩小开发和生产环境之间的差距。本文针对工具差距,特别是在使用 Spring Testcontainers 进行集成测试方面,作为使开发和生产尽可能相似的一种方式。
在进行涉及数据库的集成测试时,我们必须仔细管理所有的CRUD操作。这在集中式数据库环境中至关重要,在这种环境中,诸如 TestDeleteUserByID_ShouldReturnOk() 之类的测试可能会“意外地”决定删除自 2015 年以来一直与我们合作的最忠实客户的帐户?‍♂️
为了减轻此类风险,我们可以考虑数据库事务等解决方案来隔离测试数据。例如,测试可以启动一个事务来修改数据,然后在最后回滚,从而使数据库保持原始状态。
但是,这引发了一个关键问题:测试的内容是什么?

Dev/prod parity : Spring Boot Testcontainers

如果隔离失败并且代码执行的更改未回滚,导致数据泄漏到生产环境怎么办?这种情况下的潜在损害是巨大的。

另外,使用 H2DB 等内存数据库进行独立测试也带来了一些挑战。即使设置很容易,H2DB 与 RDBMS 不同,因此开发环境和生产环境之间的测试很可能会产生不同的结果,因此我们不能相信这些结果。

https://stackoverflow.com/questions/62778900/syntax-error-h2-database-in-postgresql-compatibility

下一个问题较少的解决方案是克隆数据库,通过类似生产的环境提供风险较小的方法。然而,这种方法也有其局限性。鉴于 ORM 自动创建和设置生产数据库模式,我们需要考虑如何保持克隆的开发数据库同步。


测试您可以容器化的任何内容:数据库、消息代理等等

“Testcontainers 是一个支持 JUnit 测试的 Java 库,提供通用数据库、Selenium Web 浏览器或任何其他可以在 Docker 容器中运行的东西的轻量级一次性实例。”

它最初是为 Java 开发的,后来扩展到支持其他语言,如 Go、Rust 和 .NET。

Testcontainers 的主要思想是提供一个可从 IDE 运行的按需基础设施,无需模拟或使用内存服务即可进行测试,并且可以自动清理。

我们可以通过三个步骤来实现这一目标:

  • 启动所需的服务并通过设置 Docker 容器来准备基础设施,并将您的应用程序配置为使用此设置作为测试基础设施。
  • 在 Docker 化基础设施上运行测试。
  • 测试结束后自动清理docker化基础设施

Testcontainers 库文档


Spring Boot 测试容器实现

在集成测试的基类ApplicationIntegrationTests中,我们定义了一个静态的PostgreSQLContainer。此容器用于从此类派生的所有测试实例。

@Testcontainers 注解可以发现所有用 @Container 注解的字段,管理其容器生命周期方法,并启动容器。

  • 声明为静态字段的容器在测试方法之间共享。它们仅在执行任何测试方法之前启动一次,并在执行最后一个测试方法后停止。
  • 声明为实例字段的容器会针对每个测试方法启动和停止。

@DynamicPropertySource 注解允许我们动态地将属性注入到我们的测试环境中。

@Testcontainers
@ActiveProfiles("test")
public abstract class ApplicationIntegrationTests {
    @Container
    protected static PostgreSQLContainer<?> postgres=new PostgreSQLContainer<>("postgres:17.2-alpine")
            .withDatabaseName("testcontainersproject")
            .withUsername("root")
            .withPassword("root");

    @DynamicPropertySource
    static void initialize(DynamicPropertyRegistry registry)
    {
        registry.add("spring.datasource.url",postgres::getJdbcUrl);
        registry.add("spring.datasource.username",postgres::getUsername);
        registry.add("spring.datasource.password",postgres::getPassword);
    }


}
登录后复制

或者,我们可以跳过使用@Testcontainers和@Container,而是直接使用@BeforeAll和@AfterAll来管理容器生命周期。这种方法可以更好地控制容器启动和停止的时间和方式

@BeforeAll
public static void runContainer(){
        postgres.start();
}
@AfterAll
static void stopContainers() {
    postgres.stop();
}

登录后复制

在@AfterAll回调方法中,我们显式停止Postgres容器。但是,即使我们没有显式停止容器,Testcontainers 也会在测试运行结束时自动清理并关闭容器。

现在我们可以通过扩展 ApplicationIntegrationTests 来创建集成测试,如下所示。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class CategoryControllerTest extends ApplicationIntegrationTests {
    private static final String CATEGORY_ENDPOINT="/categories";
   @Autowired
    private MockMvc mockMvc;
    @Autowired
    private CategoryRepository categoryRepository;

    @Test
    void TestGetAllCategories_ShouldReturnOk() throws Exception {

        List<Category> categories = List.of(
                new Category("Electronics", "All kinds of electronic gadgets from smartphones to laptops"),
                new Category("Books", "A wide range of books from novels to educational textbooks")
        );
        categoryRepository.saveAll(categories);
        MvcResult mvcResult=mockMvc.perform(
                get(CATEGORY_ENDPOINT).
                        contentType(MediaType.APPLICATION_JSON)
        )
                .andExpect(status().isOk())
                .andReturn();
        var response=mvcResult.getResponse().getContentAsString();
        assertNotNull(response);
        assertFalse(response.isEmpty());
    }
}
登录后复制

以上是开发/产品奇偶校验:Spring Boot Testcontainers的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

公司安全软件导致应用无法运行?如何排查和解决? 公司安全软件导致应用无法运行?如何排查和解决? Apr 19, 2025 pm 04:51 PM

公司安全软件导致部分应用无法正常运行的排查与解决方法许多公司为了保障内部网络安全,会部署安全软件。...

如何使用MapStruct简化系统对接中的字段映射问题? 如何使用MapStruct简化系统对接中的字段映射问题? Apr 19, 2025 pm 06:21 PM

系统对接中的字段映射处理在进行系统对接时,常常会遇到一个棘手的问题:如何将A系统的接口字段有效地映�...

如何优雅地获取实体类变量名构建数据库查询条件? 如何优雅地获取实体类变量名构建数据库查询条件? Apr 19, 2025 pm 11:42 PM

在使用MyBatis-Plus或其他ORM框架进行数据库操作时,经常需要根据实体类的属性名构造查询条件。如果每次都手动...

如何将姓名转换为数字以实现排序并保持群组中的一致性? 如何将姓名转换为数字以实现排序并保持群组中的一致性? Apr 19, 2025 pm 11:30 PM

将姓名转换为数字以实现排序的解决方案在许多应用场景中,用户可能需要在群组中进行排序,尤其是在一个用...

IntelliJ IDEA是如何在不输出日志的情况下识别Spring Boot项目的端口号的? IntelliJ IDEA是如何在不输出日志的情况下识别Spring Boot项目的端口号的? Apr 19, 2025 pm 11:45 PM

在使用IntelliJIDEAUltimate版本启动Spring...

Java对象如何安全地转换为数组? Java对象如何安全地转换为数组? Apr 19, 2025 pm 11:33 PM

Java对象与数组的转换:深入探讨强制类型转换的风险与正确方法很多Java初学者会遇到将一个对象转换成数组的�...

电商平台SKU和SPU数据库设计:如何兼顾用户自定义属性和无属性商品? 电商平台SKU和SPU数据库设计:如何兼顾用户自定义属性和无属性商品? Apr 19, 2025 pm 11:27 PM

电商平台SKU和SPU表设计详解本文将探讨电商平台中SKU和SPU的数据库设计问题,特别是如何处理用户自定义销售属...

使用TKMyBatis进行数据库查询时,如何优雅地获取实体类变量名构建查询条件? 使用TKMyBatis进行数据库查询时,如何优雅地获取实体类变量名构建查询条件? Apr 19, 2025 pm 09:51 PM

在使用TKMyBatis进行数据库查询时,如何优雅地获取实体类变量名以构建查询条件,是一个常见的难题。本文将针...

See all articles