Spring Boot 如何在使用JUnit、Sping Boot 和TestContainers的集成测试中防止数据冲突?

qxsslcnc  于 2022-11-23  发布在  Spring
关注(0)|答案(3)|浏览(154)

我正在Sping Boot 中使用Junit,沿着TestContainers(Docker,MySQL 8.0.29)来开发集成测试。
当我单独执行测试时,它们都成功了。但是当我同时运行它们时(即在CI/CD中),它们失败了。这是因为测试没有按顺序执行,并且在执行查找项的测试之前,项可能已经被删除。
为了解决这个问题,我想给予实体一个唯一的ID。但是,这个ID已经在我的Hibernate实体中自动设置:

@Entity
public class Assignment {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

我曾尝试在执行每个测试之前删除所有项目,但这不起作用:

@Autowired
    private JdbcTemplate jdbcTemplate;

    @BeforeEach
    void tearDown() {
        JdbcTestUtils.deleteFromTables(jdbcTemplate, "assignment");
    }

集成测试示例:

@Test
    void When_getById_Verify_Fields() {
        AssignmentDTO assignmentDTO = new AssignmentDTO();
        assignmentDTO.setTitle("test");
        assignmentDTO.setDescription("test");
        assignmentDTO.setUserId("1");
        assignmentDTO.setCreator("1");

        assignmentService.addAssignment(assignmentDTO);

        AssignmentDTO expectedAssignment = assignmentService.getById(1);

        assertEquals(assignmentDTO.getTitle(), expectedAssignment.getTitle());
        assertEquals(assignmentDTO.getDescription(), expectedAssignment.getDescription());
        assertEquals(assignmentDTO.getUserId(), expectedAssignment.getUserId());
        assertEquals(assignmentDTO.getCreator(), expectedAssignment.getCreator());
    }
dluptydi

dluptydi1#

每个测试方法通常都应该删除它创建的数据,以防止出现此问题。
您可以执行哪些操作以使数据不提交到数据库中?如果您希望将@Transactional注解用于所有测试方法,可以将其添加到测试方法或测试类中。这将在测试方法之后执行回滚。

scyqe7ek

scyqe7ek2#

如果希望在每次测试之前或之后执行SQL脚本,可以使用org.springframework.test.context.jdbc中注解。
以及如何在测试中使用它的示例:

@SqlGroup({
        @Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = {
                "classpath:datasets/integration/integration_test_before.sql"}),
        @Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts = {
                "classpath:datasets/integration/integration_test_after.sql"})})

此注解需要添加到类测试中。使用此注解,您将在测试之前和之后执行脚本,以初始化数据和删除数据。
SQL文件的格式必须为src/test/resources/datasets/integration
您可以找到使用指南的链接:https://www.baeldung.com/spring-boot-data-sql-and-schema-sql

7vux5j2d

7vux5j2d3#

通过返回保存在addAssignmentid中的对象,可以很容易地解决这个问题。

AssignmentDTO assignment = assignmentService.addAssignment(assignmentDTO);

AssignmentDTO expectedAssignment = assignmentService.getById(assignment.getId());

除了删除所有数据之外,失败的原因是自动增量仍然存在。请参阅this以重置自动增量。

相关问题