如何使用SpringBootTest启用JPA审计?

问题描述 投票:0回答:1

我想为我的 RestAPI 端点编写集成测试,但我正在努力解决 @EnableJpaAuditing。我希望 Spring 审核我的一些实体,因此我创建了以下配置类:

@Configuration
@EnableJpaAuditing
public class PersistenceAuditConfiguration {

}

我将其导入到我的主应用程序配置中:

@ServletComponentScan
@SpringBootApplication
@Import(PersistenceAuditConfiguration.class)
public class TMTWebApplication {

    public static void main(String[] args)  {
        SpringApplication.run(TMTWebApplication.class, args);
    }
}

此外,我有一个用于我想要审核的所有实体的抽象基类:

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true)
public abstract class AuditableEntity extends EpicPojo implements Serializable {

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, updatable = false)
@CreatedDate
private Date createdAt;

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated_at", nullable = false)
@LastModifiedDate
private Date updatedAt;

    //...and so on

}

在我的application.yml中,我设置了以下属性:

spring:
    datasource:
        url: jdbc:postgresql://localhost:5432/tmt
        username: whoever
        password: whatever
        driver-class-name: org.postgresql.Driver
    flyway:
        baselineOnMigrate: true
        locations: classpath:db/migration
    jpa:
        hibernate:
            ddl-auto: update
        generate-ddl: true
        properties:
            hibernate:
                dialect: org.hibernate.dialect.PostgreSQL10Dialect
                jdbc:
                    lob:
                        non_contextual_creation: true

这样,我可以在 Flyway 迁移脚本中省略审核字段(列)。当我在空数据库上正常启动应用程序时,将为继承自 AuditableEntity 的每个实体创建审核列 created_atupdated_at

现在,我想使用 @SpringBootTest 注释运行集成测试,因此我期望整个应用程序上下文以几乎相同的方式启动。不幸的是,事实并非如此。我使用 Zonky 的嵌入式 Postgres 进行测试,因为我有一些 JSONB 数据类型。设置工作无缝进行,但不幸的是未创建审核字段。我的测试课如下所示:

@RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc @AutoConfigureEmbeddedDatabase @FlywayTest @Import(PersistenceAuditConfiguration.class) public class AuthController_IntegrationTest { //... testy-testy, test, test }

第一个测试将向我的审核用户表插入(注册)一个新用户并返回它,但由于以下异常而失败:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet [stack trace omitted] Caused by: org.postgresql.util.PSQLException: ERROR: column roleentity0_.created_at does not exist

我发现了很多类似的问题,但大多数都处理@DataJpaTest而不是@SpringBootTest(此时我不想单独测试不同的层)。根据我能找到的不同线索和问题,我还尝试了以下方法:

  • 直接在TMTWebApplication配置类上@EnableJpaAuditing,这是编写集成测试之前的第一个也是原始的方法。

  • @EnableJPAAudidting 直接在我的测试类上,这导致了 BeanDefinitionOverrideException。在我不情愿地允许bean重写后,我再次遇到了上面的异常(created_at不存在)。

我可以看到 Github 上的

thisthis 线程存在问题,但我还不了解 Spring 针对此特定配置的底层设计,并且文档也没有真正帮助。 请注意:我昨天问过与此问题类似的问题,但我删除了它。我怀疑这与 Zonky 的嵌入式 Postgres 实例不理解应用程序属性有关,但我想这是错误的,所以我不得不重新表述它以仅关注 Spring。我想,我错过了这里周围所有树木的森林,所以如果有人能指出我正确的树,我将非常感激。预先感谢!

java spring-boot spring-data-jpa spring-boot-test auditing
1个回答
0
投票
要使用

@SpringBootTest

 在集成测试中启用 JPA 审核,请按照以下步骤操作:

  1. 启用 JPA 审核:将 @EnableJpaAuditing

     直接添加到您的测试类。

    @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc @AutoConfigureEmbeddedDatabase @FlywayTest @EnableJpaAuditing public class AuthController_IntegrationTest { // Your test methods }
    
    
  2. 允许 Bean 定义覆盖:如果遇到 BeanDefinitionOverrideException

    ,请通过将其添加到您的
    application-test.yml
    来允许 Bean 覆盖:

    spring: main: allow-bean-definition-overriding: true
    
    
  3. 检查数据库初始化:确保使用实体定义正确初始化嵌入式 PostgreSQL 数据库。查找指示表创建的日志。

  4. 验证 Flyway 迁移:确保 Flyway 迁移正确应用于嵌入式数据库。检查测试日志中的迁移历史记录。

© www.soinside.com 2019 - 2024. All rights reserved.