用嵌入式数据库替换真实数据源进行测试

时间:2019-10-06 22:12:29

标签: java postgresql spring-boot junit5

我的Spring Boot应用程序中有两个数据源。都这样声明:

@Lazy
@Configuration
@EnableJpaRepositories(
        basePackages = "com.nws.signer.db.dao",
        entityManagerFactoryRef = "signerEntityManager",
        transactionManagerRef = "signerTransactionManager"
)
@EnableTransactionManagement
public class SignerJPAConfig {
    private Map<String, String> sig_db_props;
    private String sig_url;

    @Autowired
    private VedProfiledPropsSource p;

    @PostConstruct
    public void init() {
        sig_db_props = new HashMap<>();

        sig_url =
                String.format("jdbc:postgresql://%s:%s/%s", p.getSigDbHost(), p.getSigDbPort(), p.getSigDbName());

        sig_db_props.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL92Dialect");
        sig_db_props.put("javax.persistence.jdbc.url", sig_url);
        sig_db_props.put("javax.persistence.jdbc.user", p.getSigDbUser());
        sig_db_props.put("javax.persistence.jdbc.password", p.getSigDbPassword());
        sig_db_props.put("hibernate.connection.autocommit", "true");
        sig_db_props.put("hibernate.cache.use_second_level_cache", "false");
        sig_db_props.put("hibernate.hbm2ddl.auto", "update");
    }
...
}

所以我正在使用VedProfiledPropsSource,它是@ConfigurationProperties,具有所使用的特定配置文件的属性。在postConstruct中初始化jpaPropertyMap后,我将其设置为LocalContainerEntityManagerFactoryBean,并与DataSourcePlatformTransactionManager一起声明为bean。对于其他数据源相同。

现在我要使用embedded-database-spring-test依赖项:

        <dependency>
            <groupId>io.zonky.test</groupId>
            <artifactId>embedded-database-spring-test</artifactId>
            <version>1.5.1</version>
            <scope>test</scope>
        </dependency>

引导嵌入式数据库进行测试,并将我的数据源连接到该数据库。构建机器没有数据库,所以我想在测试范围内使用它。

我的e2e测试课程始于:

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@ExtendWith(SpringExtension.class)
@Transactional
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {VedicaConfig.class})
@AutoConfigureMockMvc
@ActiveProfiles("mvntest")
@FlywayTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureEmbeddedDatabase(beanName = "signerJPAConfig")
public class RESTTest {
...
}

所以我在想它将引导内存中的postgresql数据库并替换(用魔术)命名的数据源,而flyway将应用迁移脚本。

现在我缺少/误解了一些东西,因为这没有发生,并且我的数据源配置Bean仍尝试使用配置文件属性文件中正确显示的凭据连接到数据库。并失败:

2019-10-07 00:05:53.785 ERROR 40358 --- [  prefetching-3] org.postgresql.Driver                    : Connection error: 

org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:245) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:195) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.Driver.makeConnection(Driver.java:452) ~[postgresql-42.2.2.jar:42.2.2]
    at org.postgresql.Driver.connect(Driver.java:254) ~[postgresql-42.2.2.jar:42.2.2]
    at java.sql.DriverManager.getConnection(DriverManager.java:664) [na:1.8.0_66]
    at java.sql.DriverManager.getConnection(DriverManager.java:208) [na:1.8.0_66]
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:154) [spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:145) [spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:205) [spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:169) [spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:56) [flyway-core-5.2.4.jar:na]
    at org.flywaydb.core.internal.database.DatabaseFactory.createDatabase(DatabaseFactory.java:72) [flyway-core-5.2.4.jar:na]
    at org.flywaydb.core.Flyway.execute(Flyway.java:1670) [flyway-core-5.2.4.jar:na]
    at org.flywaydb.core.Flyway.migrate(Flyway.java:1356) [flyway-core-5.2.4.jar:na]
    at io.zonky.test.db.flyway.DefaultFlywayDataSourceContext$FlywayDatabasePreparer.prepare(DefaultFlywayDataSourceContext.java:173) [embedded-database-spring-test-1.5.1.jar:na]
    at io.zonky.test.db.provider.impl.ZonkyPostgresDatabaseProvider$DatabaseInstance$DatabaseTemplate.<init>(ZonkyPostgresDatabaseProvider.java:147) [embedded-database-spring-test-1.5.1.jar:na]
    at io.zonky.test.db.provider.impl.ZonkyPostgresDatabaseProvider$DatabaseInstance$DatabaseTemplate.<init>(ZonkyPostgresDatabaseProvider.java:136) [embedded-database-spring-test-1.5.1.jar:na]
    at io.zonky.test.db.provider.impl.ZonkyPostgresDatabaseProvider$DatabaseInstance$1.load(ZonkyPostgresDatabaseProvider.java:120) [embedded-database-spring-test-1.5.1.jar:na]
    at io.zonky.test.db.provider.impl.ZonkyPostgresDatabaseProvider$DatabaseInstance$1.load(ZonkyPostgresDatabaseProvider.java:118) [embedded-database-spring-test-1.5.1.jar:na]
    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3542) [signer-1.0-SNAPSHOT.jar:na]
    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2323) [signer-1.0-SNAPSHOT.jar:na]
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2286) [signer-1.0-SNAPSHOT.jar:na]
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201) [signer-1.0-SNAPSHOT.jar:na]
    at com.google.common.cache.LocalCache.get(LocalCache.java:3953) [signer-1.0-SNAPSHOT.jar:na]
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3957) [signer-1.0-SNAPSHOT.jar:na]
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4875) [signer-1.0-SNAPSHOT.jar:na]
    at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4881) [signer-1.0-SNAPSHOT.jar:na]
    at io.zonky.test.db.provider.impl.ZonkyPostgresDatabaseProvider$DatabaseInstance.getTemplate(ZonkyPostgresDatabaseProvider.java:133) [embedded-database-spring-test-1.5.1.jar:na]
    at io.zonky.test.db.provider.impl.ZonkyPostgresDatabaseProvider.getDatabase(ZonkyPostgresDatabaseProvider.java:94) [embedded-database-spring-test-1.5.1.jar:na]
    at io.zonky.test.db.provider.impl.PrefetchingDatabaseProvider$PrefetchingTask.lambda$new$0(PrefetchingDatabaseProvider.java:252) [embedded-database-spring-test-1.5.1.jar:na]
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) ~[na:1.8.0_66]
    at java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:1.8.0_66]
    at io.zonky.test.db.provider.impl.PrefetchingDatabaseProvider$PrefetchingTask.run(PrefetchingDatabaseProvider.java:259) [embedded-database-spring-test-1.5.1.jar:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_66]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_66]
    at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_66]
Caused by: java.net.ConnectException: Connection refused

请告诉我我该怎么做才能用嵌入式的替代真实的数据源? 谢谢

1 个答案:

答案 0 :(得分:0)

对我来说,这行得通。如果您有一个带有JPA(实体和存储库)的Spring启动项目,则可以创建以下测试:

@ExtendWith(SpringExtension.class)
@DataJpaTest(excludeAutoConfiguration = { LiquibaseAutoConfiguration.class })
@AutoConfigureEmbeddedDatabase
@ActiveProfiles("junit")
public class JpaTest {

    @Autowired
    private MyRepository repo;

    @Test
    public void create(){
    ...
    }

请确保设置以下属性:

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database=POSTGRESQL