Spring WebFlux和TestContainers-通过R2DBC URL方案启动的数据库容器错误
我正在尝试在我的第一个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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论