There are articles on how to test Spring cloud stream applications without connecting to a messaging system with spring-cloud-stream-test-support. But I want to really connect to RabbitMQ from my integration test, and cannot do that. Here is test class:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableBinding(Source.class)
public class StreamIT {
@Autowired
private Source source;
@Test
public void testMessageSending() throws InterruptedException {
source.output().send(MessageBuilder.withPayload("test").build());
System.out.println("Message sent.");
}
}
Everything is the same as in @SpringBootApplication, they use the same properties from application.yml.
But there is no log line that message is sent ( osarcCachingConnectionFactory : Created new connection: SpringAMQP#22e79d25:0/SimpleConnection@5cce3ab6 [delegate=amqp://guest@127.0.1.1:5672/, localPort= 60934]
), and even if broker is not started, there is no java.net.ConnectException: Connection refused (Connection refused)
.
Am I doing something wrong? What is needed to create real connection to broker and send message from test?
EDIT
You need to remove the test-support jar from the pom. It's presence (in test scope) is what triggers replacing the real binder with a test binder.
After removing the test binder support, this works fine for me...
@RunWith(SpringRunner.class)
@SpringBootTest
public class So49816044ApplicationTests {
@Autowired
private Source source;
@Autowired
private AmqpAdmin admin;
@Autowired
private RabbitTemplate template;
@Test
public void test() {
// bind an autodelete queue to the destination exchange
Queue queue = this.admin.declareQueue();
this.admin.declareBinding(new Binding(queue.getName(), DestinationType.QUEUE, "mydest", "#", null));
this.source.output().send(new GenericMessage<>("foo"));
this.template.setReceiveTimeout(10_000);
Message received = template.receive(queue.getName());
assertThat(received.getBody()).isEqualTo("foo".getBytes());
}
}
Although there is not a rabbit sample; there is a kafka sample that uses a real (embedded) kafka binder for testing , although the test jar is excluded, it doesn't explicitly say that's needed.
Since you are using @SpringBootTest
annotation in your test, Spring Boot will evaluate all available auto-configurations.
If you have spring-cloud-stream-test-support
dependency in your test classpath then following auto-configurations will be also evaluated:
org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration
org.springframework.cloud.stream.test.binder.MessageCollectorAutoConfiguration
As a result, you have only one binder in the application context - org.springframework.cloud.stream.test.binder.TestSupportBinder
. By its name, you can understand that it does nothing about real binding.
Excluding/removing of spring-cloud-stream-test-support
dependency from test classpath - is a dubious solution. Since it forces you to create two separate modules for unit and integration tests.
If you want to exclude previously mentioned auto-configurations in your test. You can do it as follows:
@RunWith(SpringRunner.class)
@SpringBootTest
@EnableAutoConfiguration(exclude = {TestSupportBinderAutoConfiguration.class, MessageCollectorAutoConfiguration.class})
public class StreamIT {
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.