It’s not rare to have to test your application but deploying the
infrastructure can be cumbersome. While Docker or Test Containers have
improved the testing experience, you may want to mock this
infrastructure.
SmallRye Reactive Messaging proposes an in-memory connector for this
exact purpose. It allows switching the connector used for a channel with
an in-memory connector. This in-memory connector provides a way to
send messages to incoming channels, or check the received messages for
outgoing channels.
To use the in-memory connector, you need to add the following
dependency to your project:
packagetesting;importjakarta.enterprise.inject.Any;importjakarta.inject.Inject;importorg.junit.jupiter.api.AfterAll;importorg.junit.jupiter.api.Assertions;importorg.junit.jupiter.api.BeforeAll;importorg.junit.jupiter.api.Test;importio.smallrye.reactive.messaging.memory.InMemoryConnector;importio.smallrye.reactive.messaging.memory.InMemorySink;importio.smallrye.reactive.messaging.memory.InMemorySource;publicclassMyTest{// 1. Switch the channels to the in-memory connector:@BeforeAllpublicstaticvoidswitchMyChannels(){InMemoryConnector.switchIncomingChannelsToInMemory("prices");InMemoryConnector.switchOutgoingChannelsToInMemory("processed-prices");}// 2. Don't forget to reset the channel after the tests:@AfterAllpublicstaticvoidrevertMyChannels(){InMemoryConnector.clear();}// 3. Inject the in-memory connector in your test,// or use the bean manager to retrieve the instance@Inject@AnyInMemoryConnectorconnector;@Testvoidtest(){// 4. Retrieves the in-memory source to send messageInMemorySource<Integer>prices=connector.source("prices");// 5. Retrieves the in-memory sink to check what is receivedInMemorySink<Integer>results=connector.sink("processed-prices");// 6. Send fake messages:prices.send(1);prices.send(2);prices.send(3);// 7. Check you have received the expected messagesAssertions.assertEquals(3,results.received().size());}}
When switching a channel to the in-memory connector, all the
configuration properties are ignored.
Important
This connector has been designed for testing purpose only.
The switch methods return Map<String, String> instances containing
the set properties. While these system properties are already set, you
can retrieve them and pass them around, for example if you need to start
an external process with these properties:
The in-memory connector support the broadcast and merge attributes.
So, if your connector is configured with broadcast: true, the
connector broadcasts the messages to all the channel consumers. If your
connector is configured with merge:true, the connector receives all
the messages sent to the mapped channel even when coming from multiple
producers.