无法在 spring 模块集成测试中自动创建 table
Unable to get table autocreated in spring module integration test
我的项目中有一个 parameters
模块,其他模块依赖于该模块。我想以单独的方式为这个模块编写集成测试。这个模块是一个基于 spring 的模块,并且有一些与数据库相关的逻辑,尽管数据库迁移脚本在这个模块中不可用,因为它超出了它的职责范围。顺便说一句,内存中的 H2 实例用于测试目的。
我想要实现的是 spring/hibernate 基于此模块中存在的单个 @Entity
class 创建数据库 table,它被称为 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
并像这样定义集成测试class:
@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
class 调用存储库 class,后者又对数据库进行一些调用以从数据库中检索参数实体,这些调用失败,因为 SYSTEM_PARAMETERS
丢失。
任何人都可以让我知道我在这里遗漏了什么以及如何根据项目中存在的实体制作 spring 或休眠创建 table 。即使我可以调试它的地方也很高兴知道。
似乎我需要另一个可以触发此功能的神奇东西,但我无法弄清楚我到底需要什么。
非常感谢任何帮助,非常感谢您抽出宝贵时间!
p.s。我不能使用 @SpringBootTest
注释,因为此模块仅使用一些 spring 功能,而不是 spring 引导应用程序本身。它在另一个 spring 启动应用程序中用作依赖项。
你还能用@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;
}
}
使用的依赖项(通过依赖项管理和 Spring 2.3 版的引导 BOM。4.RELEASE):
<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
,因为这才是真正在幕后执行的。我使用这种方法是因为我的项目需要一些额外的步骤来设置数据库,但是,对于某些用例来说它可能太复杂了。
我的项目中有一个 parameters
模块,其他模块依赖于该模块。我想以单独的方式为这个模块编写集成测试。这个模块是一个基于 spring 的模块,并且有一些与数据库相关的逻辑,尽管数据库迁移脚本在这个模块中不可用,因为它超出了它的职责范围。顺便说一句,内存中的 H2 实例用于测试目的。
我想要实现的是 spring/hibernate 基于此模块中存在的单个 @Entity
class 创建数据库 table,它被称为 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
并像这样定义集成测试class:
@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
class 调用存储库 class,后者又对数据库进行一些调用以从数据库中检索参数实体,这些调用失败,因为 SYSTEM_PARAMETERS
丢失。
任何人都可以让我知道我在这里遗漏了什么以及如何根据项目中存在的实体制作 spring 或休眠创建 table 。即使我可以调试它的地方也很高兴知道。
似乎我需要另一个可以触发此功能的神奇东西,但我无法弄清楚我到底需要什么。
非常感谢任何帮助,非常感谢您抽出宝贵时间!
p.s。我不能使用 @SpringBootTest
注释,因为此模块仅使用一些 spring 功能,而不是 spring 引导应用程序本身。它在另一个 spring 启动应用程序中用作依赖项。
你还能用@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;
}
}
使用的依赖项(通过依赖项管理和 Spring 2.3 版的引导 BOM。4.RELEASE):
<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
,因为这才是真正在幕后执行的。我使用这种方法是因为我的项目需要一些额外的步骤来设置数据库,但是,对于某些用例来说它可能太复杂了。