我正在按照教程 [此处][1] 使用 TestContainers 为项目编写集成测试。我遇到了很多错误,我设法解决了这些错误,但无法通过以下错误。
caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: Driver org.testcontainers.jdbc.ContainerDatabaseDriver claims to not accept jdbcUrl, jdbc:postgresql://localhost:55101/test?loggerLevel=OFF
和
Caused by: java.lang.RuntimeException: Driver org.testcontainers.jdbc.ContainerDatabaseDriver claims to not accept jdbcUrl, jdbc:postgresql://localhost:55101/test?loggerLevel=OFF
这是我的应用程序属性
spring.datasource.url=jdbc:postgresql:13.6:///proforma?TC_DAEMON=true
spring.datasource.username=test
spring.datasource.password=pass
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.jpa.hibernate.ddl-auto=update
logging.level.org.hibernate.SQL=DEBUG
feign.autoconfiguration.jackson.enabled=true
feign.client.config.product.connect-timeout=5000
feign.client.config.product.read-timeout=5000
feign.client.config.product.logger-level=FULL
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.databasePlatform=org.hibernate.dialect.PostgreSQLDialect
spring.main.allow-bean-definition-overriding=true
spring.profiles.active = dev
我的基础存储库:
@DataJpaTest
@Testcontainers
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = BaseRepositoryTest.DataSourceInitializer.class)
public abstract class BaseRepositoryTest {
@Container
private static final PostgreSQLContainer<?> database = new PostgreSQLContainer<>("postgres");
public static class DataSourceInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>{
@Override
public void initialize(@NotNull ConfigurableApplicationContext applicationContext){
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
applicationContext,
"spring.test.database.replace=none", //tells springs not to start in-memory db for test
"spring.datasource.url=" + database.getJdbcUrl(),
"spring.datasource.username=" + database.getUsername(),
"spring.datasource.password=" + database.getPassword()
);
}
}
}
存储库测试:
@DataJpaTest
@DisplayName("HistoryRepository test.")
class HistoryRepositoryTest extends BaseRepositoryTest {
@Autowired
private HistoryRepository historyRepository;
@AfterEach
void tearDown(){
historyRepository.deleteAll();
}
@Test
void createHistory(){
HistoryEntity historyEntity = new HistoryEntity();
historyEntity.setMyEntity(new MyEntity());
historyEntity.setEvent("test event");
historyEntity.setLoggedUser("user");
historyEntity.setVersion(1L);
historyEntity.setEventDate(LocalDateTime.now());
historyRepository.saveAndFlush(historyEntity);
List<HistoryEntity> historyEntityList = historyRepository.findAll();
assertEquals(1, historyEntityList.size());
}
}
我搜索过类似的错误,但没有一个建议对我有用。
在哪里启动容器?
尝试启动容器:
public class TestContainerContext {
private static final PostgreSQLContainer<?> POSTGRE_SQL_CONTAINER;
static {
POSTGRE_SQL_CONTAINER = new PostgreSQLContainer<>(DockerImageName.parse(PostgreSQLContainer.IMAGE).withTag("15.1"));
POSTGRE_SQL_CONTAINER.setCommand("postgres", "-c", "max_connections=50000", "-c", "idle_in_transaction_session_timeout=300s");
POSTGRE_SQL_CONTAINER.start();
}
public static JdbcDatabaseContainer<?> getDbContainer() {
return POSTGRE_SQL_CONTAINER;
}
}
然后将您的
initialize
更改为:
@Override
public void initialize(@NotNull ConfigurableApplicationContext applicationContext) {
TestPropertyValues.of(Map.of(
"spring.datasource.url", TestContainerContext.getDbContainer().getJdbcUrl(),
"spring.datasource.driver-class-name", TestContainerContext.getDbContainer().getDriverClassName(),
"spring.datasource.username", TestContainerContext.getDbContainer().getUsername(),
"spring.datasource.password", TestContainerContext.getDbContainer().getPassword()))
.applyTo(applicationContext);
}