【问题标题】:Unable to get table autocreated in spring module integration test无法在 spring 模块集成测试中自动创建表
【发布时间】:2021-10-27 14:28:24
【问题描述】:

我的项目中有一个 parameters 模块,其他模块依赖于该模块。我想以单独的方式为此模块编写集成测试。这个模块是一个基于 spring 的模块,并且有一些与 db 相关的逻辑,尽管 db 迁移脚本在这个模块中不可用,因为它超出了它的职责范围。顺便说一句,内存中的 H2 实例用于测试目的。

我想要实现的是让 spring/hibernate 基于此模块中存在的单个 @Entity 类创建 DB 表,它被称为 ParameterEntity。

它是这样定义的:

@Entity
@Table(name = "SYSTEM_PARAMETERS")
public class ParameterEntity {
    @Id
    @Column(name = "id")
    private String id;
    @Column(name = "value")
    private String value;

    // accessors go here...
}

在我的application-test.yml 文件中,我提供了以下道具:

spring:
  jpa:
    hibernate:
      ddl-auto: create
    database: h2
    show-sql: true

并像这样定义集成测试类:

@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties
@EntityScan("path.to.package.where.parameter.entity.resides")
@ConstextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
@ActiveProfiles("test")
@TestInstance(Lifecycle.PER_CLASS)
public class ParametersIntegrationTest {
    @Autowired
    private ParameterWarden warden;
    
    @BeforeEach
    public void setUp() {
        warden.initialize();
    }

    @Configuration
    @ComponentScan("base.module.package")
    static class TestConfiguration {
        // here comes some test beans which will be used in testing purposes only
    }
}

在@BeforeEach 方法中,ParameterWarden 类调用存储库类,后者又对数据库进行一些调用以从数据库中检索参数实体,这些调用失败,因为缺少SYSTEM_PARAMETERS。

请任何人告诉我我在这里缺少什么以及如何根据我的项目中存在的实体使 spring 或 hibernate 创建表。即使是我可以调试的地方也很高兴知道。
似乎我需要另一个可以触发此功能的神奇事物,但我无法弄清楚我到底需要什么。

非常感谢任何帮助,非常感谢您的宝贵时间!

附言我不能使用@SpringBootTest 注释,因为这个模块只使用了一些弹簧特性,而不是弹簧启动应用程序本身。它在另一个 Spring Boot 应用程序中用作依赖项。

【问题讨论】:

    标签: spring spring-boot hibernate testing h2


    【解决方案1】:

    你还能用@DataJpaTest吗?

    package com.test;
    
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.extension.ExtendWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.TestPropertySource;
    import org.springframework.test.context.junit.jupiter.SpringExtension;
    
    @ExtendWith(SpringExtension.class)
    @DataJpaTest
    @ContextConfiguration(classes = TestEntityRepository.class)
    @TestPropertySource(properties = {
            "spring.jpa.hibernate.ddl-auto=create",
            "spring.datasource.platform=h2",
            "spring.jpa.show-sql=true"
    })
    @EnableAutoConfiguration
    public class IntegrationTest {
    
        @Autowired
        TestEntityRepository testEntityRepository;
    
        @Test
        void testCreateRead() {
            var saved = testEntityRepository.save(new TestEntity("test"));
    
            Assertions.assertNotNull(saved);
    
            var read = testEntityRepository.findById(saved.getId());
    
            Assertions.assertNotNull(read);
        }
    }
    

    com.test 包中的存储库和实体在哪里:

    import org.springframework.data.repository.CrudRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface TestEntityRepository extends CrudRepository<TestEntity, Long> { }
    
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import javax.persistence.*;
    
    @Entity
    @Data
    @NoArgsConstructor
    public class TestEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column
        private Long id;
    
        @Column
        private String attr;
    
        public TestEntity(String attr) {
            this.attr = attr;
        }
    }
    
    

    使用的依赖项(通过依赖管理和版本 2.3.4.RELEASE 的 Spring Boot BOM):

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    
    

    或者,如果您想将测试与 Spring 完全分离,您可以在某些实用程序逻辑中使用 org.hibernate.tool.hbm2ddl.SchemaExport,因为这才是真正在幕后执行的操作。我使用这种方法是因为我的项目需要一些额外的步骤来设置数据库,但是对于某些用例来说它可能太复杂了。

    【讨论】:

    • 非常感谢您的帮助!让我试试这个,看看这个是否适合项目的需求。
    • 是的,感谢您的帮助,忘记提供反馈了。您提出的解决方案部分有效,SchemaExport 的技巧也是一个有效的解决方案。
    猜你喜欢
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 2020-05-06
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    相关资源
    最近更新 更多