为什么每次都重新创建带有 RabbitMQ 的测试容器并且不在测试之间共享
why the test container with the RabbitMQ is creates every time anew and is not shared between the tests
我有 4 个侦听器测试,该应用程序基于 SpringBoot 构建并使用 Testcontainers,我 运行 mvn clean install,我得到以下信息:
9-08-15 18:37:01.287 INFO 8312 --- [tContainer#1-11] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:33724]
[INFO]
[INFO] Results:
[INFO]
2019-08-15 18:37:01.288 ERROR 8312 --- [tContainer#1-11] o.s.a.r.l.SimpleMessageListenerContainer : Failed to check/redeclare auto-delete queue(s).
org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:509)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:682)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:214)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2073)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2047)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2027)
at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:403)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.attemptDeclarations(AbstractMessageListenerContainer.java:1787)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.redeclareElementsIfNecessary(AbstractMessageListenerContainer.java:1768)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1195)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1041)
at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:591)
at com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:60)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1102)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1054)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:994)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:462)
... 11 common frames omitted
我对mvn clean install命令的日志文件进行了输出,上面出现了整个日志,很多次,但这不是主要问题,问题是RabbitMQ的容器启动很多次,我想在测试之间分享它。
2019-08-15 18:35:26.126 INFO --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
2019-08-15 18:35:54.665 INFO 8312 --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
2019-08-15 18:36:15.510 INFO 8312 --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
2019-08-15 18:36:31.862 INFO 8312 --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
4次,4位听众。
我尝试将 forkCount = 0 用于 maven-surefire-plugin 和 maven-failsafe-plugin,但这没有帮助。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<forkCount>0</forkCount>
</configuration>
</plugin>
@RunWith(SpringRunner.class)
@SpringBootTest(
value = {
"spring.cloud.discovery.enabled = false"
},
webEnvironment = RANDOM_PORT)
@ActiveProfiles(TEST_PROFILE)
public abstract class AbstractTest {
@LocalServerPort
private int port;
}
@ContextConfiguration(initializers = AbstractRabbitTest.Initializer.class)
public abstract class AbstractRabbitTest extends AbstractTest {
@ClassRule
public static RabbitMQContainer rabbitMQContainer = new RabbitMQContainer("rabbitmq:3.7-management")
.withExposedPorts(5672)
.withVhost("/")
.withUser("admin", "admin")
.withPermission("/", "admin", ".*", ".*", ".*");
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertyValues values = TestPropertyValues.of(
"spring.rabbitmq.host=" + rabbitMQContainer.getContainerIpAddress(),
"spring.rabbitmq.port=" + rabbitMQContainer.getMappedPort(5672),
"spring.rabbitmq.username=admin",
"spring.rabbitmq.password=admin"
);
values.applyTo(applicationContext);
}
}
}
我的每个测试都像这样并使用 spring-amqp:
public class CloseProcessListenerTest extends AbstractRabbitTest {
JUnit 中的 ClassRule 将执行每个 class 的规则,而不是每个 "suite" 的规则。由于您有多个扩展它的测试 classes,因此您在测试期间启动了多个容器。
考虑使用 the Singleton Container pattern and check Spring Boot example
我有 4 个侦听器测试,该应用程序基于 SpringBoot 构建并使用 Testcontainers,我 运行 mvn clean install,我得到以下信息:
9-08-15 18:37:01.287 INFO 8312 --- [tContainer#1-11] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:33724]
[INFO]
[INFO] Results:
[INFO]
2019-08-15 18:37:01.288 ERROR 8312 --- [tContainer#1-11] o.s.a.r.l.SimpleMessageListenerContainer : Failed to check/redeclare auto-delete queue(s).
org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:509)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:682)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:214)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2073)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2047)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2027)
at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:403)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.attemptDeclarations(AbstractMessageListenerContainer.java:1787)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.redeclareElementsIfNecessary(AbstractMessageListenerContainer.java:1768)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1195)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1041)
at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:591)
at com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:60)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1102)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1054)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:994)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:462)
... 11 common frames omitted
我对mvn clean install命令的日志文件进行了输出,上面出现了整个日志,很多次,但这不是主要问题,问题是RabbitMQ的容器启动很多次,我想在测试之间分享它。
2019-08-15 18:35:26.126 INFO --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
2019-08-15 18:35:54.665 INFO 8312 --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
2019-08-15 18:36:15.510 INFO 8312 --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
2019-08-15 18:36:31.862 INFO 8312 --- [ main] [rabbitmq:3.7-management] : Creating container for image: rabbitmq:3.7-management
4次,4位听众。
我尝试将 forkCount = 0 用于 maven-surefire-plugin 和 maven-failsafe-plugin,但这没有帮助。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<forkCount>0</forkCount>
</configuration>
</plugin>
@RunWith(SpringRunner.class)
@SpringBootTest(
value = {
"spring.cloud.discovery.enabled = false"
},
webEnvironment = RANDOM_PORT)
@ActiveProfiles(TEST_PROFILE)
public abstract class AbstractTest {
@LocalServerPort
private int port;
}
@ContextConfiguration(initializers = AbstractRabbitTest.Initializer.class)
public abstract class AbstractRabbitTest extends AbstractTest {
@ClassRule
public static RabbitMQContainer rabbitMQContainer = new RabbitMQContainer("rabbitmq:3.7-management")
.withExposedPorts(5672)
.withVhost("/")
.withUser("admin", "admin")
.withPermission("/", "admin", ".*", ".*", ".*");
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertyValues values = TestPropertyValues.of(
"spring.rabbitmq.host=" + rabbitMQContainer.getContainerIpAddress(),
"spring.rabbitmq.port=" + rabbitMQContainer.getMappedPort(5672),
"spring.rabbitmq.username=admin",
"spring.rabbitmq.password=admin"
);
values.applyTo(applicationContext);
}
}
}
我的每个测试都像这样并使用 spring-amqp:
public class CloseProcessListenerTest extends AbstractRabbitTest {
JUnit 中的 ClassRule 将执行每个 class 的规则,而不是每个 "suite" 的规则。由于您有多个扩展它的测试 classes,因此您在测试期间启动了多个容器。
考虑使用 the Singleton Container pattern and check Spring Boot example