Testing Spring Boot JMS with ActiveMQ Artemis and Testcontainers

blog-post-img

Currently, I’m teaching JMS with Spring Boot at the University of Applied Science in Bern, Switzerland.
We use Apache ActiveMQ Artemis as the JMS message broker. But how can we test our Spring Boot application?

Testcontainers to the rescue

Currently, there is no Testcontainers Java module for ActiveMQ Artemis. As you can see in the Testcontainers GitHub repository, there is an active activemq branch that may be released soon. But in the meantime, we need another solution.

There is GenericContainer that can be used for any container image:

@Container
static GenericContainer<?> artemis = new GenericContainer<>(DockerImageName.parse("apache/activemq-artemis:latest-alpine"))
        .withEnv("ANONYMOUS_LOGIN", "true")
        .withExposedPorts(61616);

As you can see, we need some configuration. First, we use the official ActiveMQ Artemis image, which is available in Docker Hub. Then, we set ANONYMOUS_LOGIN to true. Otherwise, we must provide username and password, which is not needed just for testing. And finally, we must expose the default port to which we want to send our message.

Now, the Artemis JMS client needs to know the URL for the connection. We can use @DynamicPropertySource for that purpose and use the information from the Testcontainers container:

@DynamicPropertySource
static void artemisProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.artemis.broker-url", () -> "tcp://%s:%d".formatted(artemis.getHost(), artemis.getMappedPort(61616)));
}

Writing the Test

Finally, everything is prepared, and we can write a test that sends and receives a message:

@Autowired
private JmsTemplate jmsTemplate;

@Test
void sendMessage() throws JMSException {
    jmsTemplate.convertAndSend("testQueue", "Hello, JMS!");

    Message message = jmsTemplate.receive("testQueue");

    assertThat(message).isInstanceOf(TextMessage.class);
    TextMessage textMessage = (TextMessage) message;
    assertThat(textMessage.getText()).isEqualTo("Hello, JMS");
 }

Conclusion

Testcontainers is a fantastic way to start resources as containers. Even if there is no pre-made container, you can always use GenericContainer to run virtually any container image.

Try it out yourself! The source code of the sample project is available on GitHub: https://github.com/simasch/spring-boot-artemis-testcontainers