Spring WebFlux和TestContainers-通过R2DBC URL方案启动的数据库容器错误

发布于 2025-02-13 01:11:58 字数 21002 浏览 2 评论 0 原文

我正在尝试在我的第一个Spring WebFlux应用程序中编写一些数据库集成测试。我喜欢@TestContainers背后的想法,我试图启动PostgreSQL容器而不是进行H2路线。我要在这里撰写官方文件:

我尝试以两种方式进行设置,使用TC配置文件并以编程方式创建容器。两者都给我一个相同的嵌套错误:

Caused by: java.net.URISyntaxException: Illegal character in scheme name at index 0: 127.0.0.1:2375
    at java.base/java.net.URI$Parser.fail(URI.java:2974)
    at java.base/java.net.URI$Parser.checkChars(URI.java:3145)
    at java.base/java.net.URI$Parser.checkChar(URI.java:3155)
    at java.base/java.net.URI$Parser.parse(URI.java:3170)
    at java.base/java.net.URI.<init>(URI.java:623)
    at java.base/java.net.URI.create(URI.java:904)
    ... 81 more

所以这不是一个完整的URL,但是我希望测试范围可以根据下面的架构处理URL。

Application-TC.Properties

spring.r2dbc.url=r2dbc:tc:postgresql:///mydb?TC_IMAGE_TAG=14.4-alpine

测试类

package com.rxjava.babybank.repository;

import com.rxjava.babybank.model.Account;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.junit.jupiter.Testcontainers;
import reactor.test.StepVerifier;

import java.util.List;

@RunWith(SpringRunner.class)
@DataR2dbcTest
@Testcontainers
@ActiveProfiles("tc")
public class AccountRepositoryTest {

    @Autowired
    AccountRepository repository;

//    private static PostgreSQLContainer<BabyPostgresqlContainer> container = BabyPostgresqlContainer.getInstance();
//
//    @DynamicPropertySource
//    public static void overrideProps(DynamicPropertyRegistry registry) {
//        registry.add("spring.r2dbc.url", () -> "r2dbc:postgresql://"
//                + container.getHost() + ":" + container.getFirstMappedPort()
//                + "/" + container.getDatabaseName());
//        registry.add("spring.r2dbc.username", container::getUsername);
//        registry.add("spring.r2dbc.password", container::getPassword);
//    }

    @AfterEach
    public void emptyRepository() {
        repository.deleteAll();
    }

    @Test
    public void shouldBeEmpty() {
        repository.findAll().as(StepVerifier::create).expectNextCount(0).verifyComplete();
    }

    @Test
    public void shouldGetInsertedValues() {
        Account acc1 = new Account("acc1", "cust1", 2000L, "RON");
        Account acc2 = new Account("acc2", "cust2", 200000L, "EUR");
        Account acc3 = new Account("acc3", "cust1", 3000L, "EUR");

        repository.saveAll(List.of(acc1, acc2, acc3));

        repository.findAll().as(StepVerifier::create).expectNextCount(3).verifyComplete();
    }
}

Babypostgresqlcontainer

package com.rxjava.babybank.integration;

import org.testcontainers.containers.PostgreSQLContainer;

public class BabyPostgresqlContainer extends PostgreSQLContainer<BabyPostgresqlContainer> {
    private static final String IMAGE_VERSION = "postgres:14.4-alpine";
    public static final String DATABASE_NAME = "mydb";
    private static BabyPostgresqlContainer container;

    private BabyPostgresqlContainer() {
        super(IMAGE_VERSION);
    }

    public static BabyPostgresqlContainer getInstance() {
        if (container == null) {
            container = new BabyPostgresqlContainer().withDatabaseName(DATABASE_NAME);
        }
        return container;
    }

    @Override
    public void start() {
        super.start();
        System.setProperty("DB_URL", container.getJdbcUrl());
        System.setProperty("DB_USERNAME", container.getUsername());
        System.setProperty("DB_PASSWORD", container.getPassword());
    }

    @Override
    public void stop() {
        //do nothing, JVM handles shut down
    }
}

我在做什么错?

PS:我知道这些不是有用的单元测试,只是试图使用默认的 @r2dbcrepository方法来弄清楚如何编写它们。

pps:完整错误

java.lang.AssertionError: expectation "expectNextCount(3)" failed (expected: count = 3; actual: counted = 0; signal: onError(org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection; nested exception is java.util.concurrent.CompletionException: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated))

    at reactor.test.MessageFormatter.assertionError(MessageFormatter.java:115)
    at reactor.test.MessageFormatter.failPrefix(MessageFormatter.java:104)
    at reactor.test.MessageFormatter.fail(MessageFormatter.java:73)
    at reactor.test.MessageFormatter.failOptional(MessageFormatter.java:88)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.checkCountMismatch(DefaultStepVerifierBuilder.java:1372)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onSignalCount(DefaultStepVerifierBuilder.java:1609)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onExpectation(DefaultStepVerifierBuilder.java:1466)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onError(DefaultStepVerifierBuilder.java:1129)
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredError(FluxUsingWhen.java:398)
    at reactor.core.publisher.FluxUsingWhen$RollbackInner.onComplete(FluxUsingWhen.java:475)
    at reactor.core.publisher.Operators.complete(Operators.java:137)
    at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onError(FluxUsingWhen.java:364)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:842)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:608)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:588)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onError(FluxFlatMap.java:451)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106)
    at reactor.core.publisher.Operators.error(Operators.java:198)
    at reactor.core.publisher.FluxError.subscribe(FluxError.java:43)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
    at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onError(FluxUsingWhen.java:220)
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106)
    at reactor.core.publisher.Operators.error(Operators.java:198)
    at reactor.core.publisher.MonoError.subscribe(MonoError.java:53)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106)
    at reactor.core.publisher.FluxRetry$RetrySubscriber.onError(FluxRetry.java:95)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172)
    at reactor.pool.AbstractPool$Borrower.fail(AbstractPool.java:475)
    at reactor.pool.SimpleDequePool.lambda$drainLoop$9(SimpleDequePool.java:431)
    at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onError(FluxDoOnEach.java:186)
    at reactor.core.publisher.MonoNext$NextSubscriber.onError(MonoNext.java:93)
    at reactor.core.publisher.MonoNext$NextSubscriber.onError(MonoNext.java:93)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription$WaitFutureCompletionSubscriptionState.lambda$enter$0(ConnectionPublisher.java:86)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887)
    at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2325)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription$WaitFutureCompletionSubscriptionState.enter(ConnectionPublisher.java:83)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription.transitionTo(ConnectionPublisher.java:55)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription$WaitRequestSubscriptionState.request(ConnectionPublisher.java:67)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription.request(ConnectionPublisher.java:45)
    at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108)
    at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108)
    at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.request(FluxDoOnEach.java:108)
    at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.request(FluxContextWrite.java:136)
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74)
    at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onSubscribe(FluxContextWrite.java:101)
    at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onSubscribe(FluxDoOnEach.java:121)
    at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70)
    at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70)
    at org.testcontainers.r2dbc.ConnectionPublisher.subscribe(ConnectionPublisher.java:29)
    at reactor.core.publisher.MonoFromPublisher.subscribe(MonoFromPublisher.java:63)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onComplete(FluxConcatArray.java:258)
    at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:78)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.core.publisher.Flux.subscribeWith(Flux.java:8639)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8436)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8360)
    at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:453)
    at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:600)
    at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:296)
    at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:430)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110)
    at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:720)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:117)
    at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:50)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4382)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172)
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134)
    at reactor.core.publisher.Operators.error(Operators.java:198)
    at reactor.core.publisher.MonoError.subscribe(MonoError.java:53)
    at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:104)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:94)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.toVerifierAndSubscribe(DefaultStepVerifierBuilder.java:891)
    at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:831)
    at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:823)
    at reactor.test.DefaultStepVerifierBuilder.verifyComplete(DefaultStepVerifierBuilder.java:690)
    at com.rxjava.babybank.repository.AccountRepositoryTest.shouldGetInsertedValues(AccountRepositoryTest.java:54)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
    Suppressed: org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection; nested exception is java.util.concurrent.CompletionException: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated
        at org.springframework.r2dbc.connection.ConnectionFactoryUtils.lambda$getConnection$0(ConnectionFactoryUtils.java:88)
        at reactor.core.publisher.Mono.lambda$onErrorMap$31(Mono.java:3730)
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94)
        ... 95 more
    Caused by: java.util.concurrent.CompletionException: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated
        at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
        at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1770)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
    Caused by: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated
        at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:586)
        at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:813)
        at java.base/java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:729)
        at java.base/java.util.ServiceLoader$3.next(ServiceLoader.java:1403)
        at java.base/java.lang.Iterable.forEach(Iterable.java:74)
        at org.testcontainers.DockerClientFactory.getOrInitializeStrategy(DockerClientFactory.java:133)
        at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:176)
        at org.testcontainers.DockerClientFactory$1.getDockerClient(DockerClientFactory.java:90)
        at com.github.dockerjava.api.DockerClientDelegate.authConfig(DockerClientDelegate.java:108)
        at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:325)
        at org.testcontainers.containers.PostgreSQLR2DBCDatabaseContainer.start(PostgreSQLR2DBCDatabaseContainer.java:12)
        at org.testcontainers.r2dbc.TestcontainersR2DBCConnectionFactory.lambda$null$3(TestcontainersR2DBCConnectionFactory.java:54)
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
        ... 3 more
    Caused by: java.lang.IllegalArgumentException: Illegal character in scheme name at index 0: 127.0.0.1:2375
        at java.base/java.net.URI.create(URI.java:906)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig$Builder.withDockerHost(DefaultDockerClientConfig.java:360)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig$Builder.withProperties(DefaultDockerClientConfig.java:342)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig.createDefaultConfigBuilder(DefaultDockerClientConfig.java:221)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig.createDefaultConfigBuilder(DefaultDockerClientConfig.java:210)
        at org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy.<init>(EnvironmentAndSystemPropertyClientProviderStrategy.java:34)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:789)
        ... 14 more
    Caused by: java.net.URISyntaxException: Illegal character in scheme name at index 0: 127.0.0.1:2375
        at java.base/java.net.URI$Parser.fail(URI.java:2974)
        at java.base/java.net.URI$Parser.checkChars(URI.java:3145)
        at java.base/java.net.URI$Parser.checkChar(URI.java:3155)
        at java.base/java.net.URI$Parser.parse(URI.java:3170)
        at java.base/java.net.URI.<init>(URI.java:623)
        at java.base/java.net.URI.create(URI.java:904)
        ... 25 more

I'm trying to write some database integration tests in my first Spring Webflux application. I liked the idea behind @Testcontainers and I'm attempting to launch a Postgresql container instead of going the H2 route. I'm going by the official documentation here : https://www.testcontainers.org/modules/databases/r2dbc/

I've tried to set this up in two ways, using a tc profile and creating the container programmatically. Both give me the same nested error:

Caused by: java.net.URISyntaxException: Illegal character in scheme name at index 0: 127.0.0.1:2375
    at java.base/java.net.URI$Parser.fail(URI.java:2974)
    at java.base/java.net.URI$Parser.checkChars(URI.java:3145)
    at java.base/java.net.URI$Parser.checkChar(URI.java:3155)
    at java.base/java.net.URI$Parser.parse(URI.java:3170)
    at java.base/java.net.URI.<init>(URI.java:623)
    at java.base/java.net.URI.create(URI.java:904)
    ... 81 more

So that's not a complete URL but I was expecting testcontainers to handle the url based on the schema below.

application-tc.properties

spring.r2dbc.url=r2dbc:tc:postgresql:///mydb?TC_IMAGE_TAG=14.4-alpine

Test class

package com.rxjava.babybank.repository;

import com.rxjava.babybank.model.Account;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.junit.jupiter.Testcontainers;
import reactor.test.StepVerifier;

import java.util.List;

@RunWith(SpringRunner.class)
@DataR2dbcTest
@Testcontainers
@ActiveProfiles("tc")
public class AccountRepositoryTest {

    @Autowired
    AccountRepository repository;

//    private static PostgreSQLContainer<BabyPostgresqlContainer> container = BabyPostgresqlContainer.getInstance();
//
//    @DynamicPropertySource
//    public static void overrideProps(DynamicPropertyRegistry registry) {
//        registry.add("spring.r2dbc.url", () -> "r2dbc:postgresql://"
//                + container.getHost() + ":" + container.getFirstMappedPort()
//                + "/" + container.getDatabaseName());
//        registry.add("spring.r2dbc.username", container::getUsername);
//        registry.add("spring.r2dbc.password", container::getPassword);
//    }

    @AfterEach
    public void emptyRepository() {
        repository.deleteAll();
    }

    @Test
    public void shouldBeEmpty() {
        repository.findAll().as(StepVerifier::create).expectNextCount(0).verifyComplete();
    }

    @Test
    public void shouldGetInsertedValues() {
        Account acc1 = new Account("acc1", "cust1", 2000L, "RON");
        Account acc2 = new Account("acc2", "cust2", 200000L, "EUR");
        Account acc3 = new Account("acc3", "cust1", 3000L, "EUR");

        repository.saveAll(List.of(acc1, acc2, acc3));

        repository.findAll().as(StepVerifier::create).expectNextCount(3).verifyComplete();
    }
}

BabyPostgresqlContainer

package com.rxjava.babybank.integration;

import org.testcontainers.containers.PostgreSQLContainer;

public class BabyPostgresqlContainer extends PostgreSQLContainer<BabyPostgresqlContainer> {
    private static final String IMAGE_VERSION = "postgres:14.4-alpine";
    public static final String DATABASE_NAME = "mydb";
    private static BabyPostgresqlContainer container;

    private BabyPostgresqlContainer() {
        super(IMAGE_VERSION);
    }

    public static BabyPostgresqlContainer getInstance() {
        if (container == null) {
            container = new BabyPostgresqlContainer().withDatabaseName(DATABASE_NAME);
        }
        return container;
    }

    @Override
    public void start() {
        super.start();
        System.setProperty("DB_URL", container.getJdbcUrl());
        System.setProperty("DB_USERNAME", container.getUsername());
        System.setProperty("DB_PASSWORD", container.getPassword());
    }

    @Override
    public void stop() {
        //do nothing, JVM handles shut down
    }
}

What am I doing wrong?

PS: I know those aren't useful unit tests, just trying to figure out how to write them using the default @R2dbcRepository methods.

PPS: Full error

java.lang.AssertionError: expectation "expectNextCount(3)" failed (expected: count = 3; actual: counted = 0; signal: onError(org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection; nested exception is java.util.concurrent.CompletionException: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated))

    at reactor.test.MessageFormatter.assertionError(MessageFormatter.java:115)
    at reactor.test.MessageFormatter.failPrefix(MessageFormatter.java:104)
    at reactor.test.MessageFormatter.fail(MessageFormatter.java:73)
    at reactor.test.MessageFormatter.failOptional(MessageFormatter.java:88)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.checkCountMismatch(DefaultStepVerifierBuilder.java:1372)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onSignalCount(DefaultStepVerifierBuilder.java:1609)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onExpectation(DefaultStepVerifierBuilder.java:1466)
    at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onError(DefaultStepVerifierBuilder.java:1129)
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredError(FluxUsingWhen.java:398)
    at reactor.core.publisher.FluxUsingWhen$RollbackInner.onComplete(FluxUsingWhen.java:475)
    at reactor.core.publisher.Operators.complete(Operators.java:137)
    at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onError(FluxUsingWhen.java:364)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:842)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:608)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:588)
    at reactor.core.publisher.FluxFlatMap$FlatMapMain.onError(FluxFlatMap.java:451)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106)
    at reactor.core.publisher.Operators.error(Operators.java:198)
    at reactor.core.publisher.FluxError.subscribe(FluxError.java:43)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
    at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onError(FluxUsingWhen.java:220)
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106)
    at reactor.core.publisher.Operators.error(Operators.java:198)
    at reactor.core.publisher.MonoError.subscribe(MonoError.java:53)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106)
    at reactor.core.publisher.FluxRetry$RetrySubscriber.onError(FluxRetry.java:95)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172)
    at reactor.pool.AbstractPool$Borrower.fail(AbstractPool.java:475)
    at reactor.pool.SimpleDequePool.lambda$drainLoop$9(SimpleDequePool.java:431)
    at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onError(FluxDoOnEach.java:186)
    at reactor.core.publisher.MonoNext$NextSubscriber.onError(MonoNext.java:93)
    at reactor.core.publisher.MonoNext$NextSubscriber.onError(MonoNext.java:93)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription$WaitFutureCompletionSubscriptionState.lambda$enter$0(ConnectionPublisher.java:86)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887)
    at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2325)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription$WaitFutureCompletionSubscriptionState.enter(ConnectionPublisher.java:83)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription.transitionTo(ConnectionPublisher.java:55)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription$WaitRequestSubscriptionState.request(ConnectionPublisher.java:67)
    at org.testcontainers.r2dbc.ConnectionPublisher$StateMachineSubscription.request(ConnectionPublisher.java:45)
    at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108)
    at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108)
    at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.request(FluxDoOnEach.java:108)
    at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.request(FluxContextWrite.java:136)
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74)
    at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onSubscribe(FluxContextWrite.java:101)
    at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onSubscribe(FluxDoOnEach.java:121)
    at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70)
    at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70)
    at org.testcontainers.r2dbc.ConnectionPublisher.subscribe(ConnectionPublisher.java:29)
    at reactor.core.publisher.MonoFromPublisher.subscribe(MonoFromPublisher.java:63)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onComplete(FluxConcatArray.java:258)
    at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:78)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.core.publisher.Flux.subscribeWith(Flux.java:8639)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8436)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8360)
    at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:453)
    at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:600)
    at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:296)
    at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:430)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110)
    at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:720)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:117)
    at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:50)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4382)
    at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172)
    at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134)
    at reactor.core.publisher.Operators.error(Operators.java:198)
    at reactor.core.publisher.MonoError.subscribe(MonoError.java:53)
    at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4397)
    at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:104)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:94)
    at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.toVerifierAndSubscribe(DefaultStepVerifierBuilder.java:891)
    at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:831)
    at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:823)
    at reactor.test.DefaultStepVerifierBuilder.verifyComplete(DefaultStepVerifierBuilder.java:690)
    at com.rxjava.babybank.repository.AccountRepositoryTest.shouldGetInsertedValues(AccountRepositoryTest.java:54)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
    Suppressed: org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection; nested exception is java.util.concurrent.CompletionException: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated
        at org.springframework.r2dbc.connection.ConnectionFactoryUtils.lambda$getConnection$0(ConnectionFactoryUtils.java:88)
        at reactor.core.publisher.Mono.lambda$onErrorMap$31(Mono.java:3730)
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94)
        ... 95 more
    Caused by: java.util.concurrent.CompletionException: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated
        at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
        at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1770)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
    Caused by: java.util.ServiceConfigurationError: org.testcontainers.dockerclient.DockerClientProviderStrategy: Provider org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy could not be instantiated
        at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:586)
        at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:813)
        at java.base/java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:729)
        at java.base/java.util.ServiceLoader$3.next(ServiceLoader.java:1403)
        at java.base/java.lang.Iterable.forEach(Iterable.java:74)
        at org.testcontainers.DockerClientFactory.getOrInitializeStrategy(DockerClientFactory.java:133)
        at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:176)
        at org.testcontainers.DockerClientFactory$1.getDockerClient(DockerClientFactory.java:90)
        at com.github.dockerjava.api.DockerClientDelegate.authConfig(DockerClientDelegate.java:108)
        at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:325)
        at org.testcontainers.containers.PostgreSQLR2DBCDatabaseContainer.start(PostgreSQLR2DBCDatabaseContainer.java:12)
        at org.testcontainers.r2dbc.TestcontainersR2DBCConnectionFactory.lambda$null$3(TestcontainersR2DBCConnectionFactory.java:54)
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
        ... 3 more
    Caused by: java.lang.IllegalArgumentException: Illegal character in scheme name at index 0: 127.0.0.1:2375
        at java.base/java.net.URI.create(URI.java:906)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig$Builder.withDockerHost(DefaultDockerClientConfig.java:360)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig$Builder.withProperties(DefaultDockerClientConfig.java:342)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig.createDefaultConfigBuilder(DefaultDockerClientConfig.java:221)
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultDockerClientConfig.createDefaultConfigBuilder(DefaultDockerClientConfig.java:210)
        at org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy.<init>(EnvironmentAndSystemPropertyClientProviderStrategy.java:34)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:789)
        ... 14 more
    Caused by: java.net.URISyntaxException: Illegal character in scheme name at index 0: 127.0.0.1:2375
        at java.base/java.net.URI$Parser.fail(URI.java:2974)
        at java.base/java.net.URI$Parser.checkChars(URI.java:3145)
        at java.base/java.net.URI$Parser.checkChar(URI.java:3155)
        at java.base/java.net.URI$Parser.parse(URI.java:3170)
        at java.base/java.net.URI.<init>(URI.java:623)
        at java.base/java.net.URI.create(URI.java:904)
        ... 25 more

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文