diff --git a/spring-jms/pom.xml b/spring-jms/pom.xml
index 09bf854221..ab202402f3 100644
--- a/spring-jms/pom.xml
+++ b/spring-jms/pom.xml
@@ -41,6 +41,25 @@
${spring-boot-test.version}
test
+
+
+ org.mockito
+ mockito-core
+ 4.6.1
+ test
+
+
+ org.apache.activemq.tooling
+ activemq-junit
+ 5.16.5
+ test
+
+
+ org.testcontainers
+ testcontainers
+ 1.17.3
+ test
+
diff --git a/spring-jms/src/main/java/com/baeldung/spring/jms/testing/JmsApplication.java b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/JmsApplication.java
new file mode 100644
index 0000000000..0a89d422b4
--- /dev/null
+++ b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/JmsApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.spring.jms.testing;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+
+@ComponentScan
+public class JmsApplication {
+
+ public static void main(String[] args) {
+ ApplicationContext context = new AnnotationConfigApplicationContext(JmsApplication.class);
+ }
+}
diff --git a/spring-jms/src/main/java/com/baeldung/spring/jms/testing/JmsConfig.java b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/JmsConfig.java
new file mode 100644
index 0000000000..92abb32861
--- /dev/null
+++ b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/JmsConfig.java
@@ -0,0 +1,34 @@
+package com.baeldung.spring.jms.testing;
+
+import javax.jms.ConnectionFactory;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jms.annotation.EnableJms;
+import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
+import org.springframework.jms.config.JmsListenerContainerFactory;
+import org.springframework.jms.core.JmsTemplate;
+
+@Configuration
+@EnableJms
+public class JmsConfig {
+
+ @Bean
+ public JmsListenerContainerFactory> jmsListenerContainerFactory() {
+ DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
+ factory.setConnectionFactory(connectionFactory());
+ return factory;
+ }
+
+ @Bean
+ public ConnectionFactory connectionFactory() {
+ return new ActiveMQConnectionFactory("tcp://localhost:61616");
+ }
+
+ @Bean
+ public JmsTemplate jmsTemplate() {
+ return new JmsTemplate(connectionFactory());
+ }
+
+}
diff --git a/spring-jms/src/main/java/com/baeldung/spring/jms/testing/MessageListener.java b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/MessageListener.java
new file mode 100644
index 0000000000..f66a99c876
--- /dev/null
+++ b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/MessageListener.java
@@ -0,0 +1,20 @@
+package com.baeldung.spring.jms.testing;
+
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MessageListener {
+
+ private static final Logger logger = LoggerFactory.getLogger(MessageListener.class);
+
+ @JmsListener(destination = "queue-1")
+ public void sampleJmsListenerMethod(TextMessage message) throws JMSException {
+ logger.info("JMS listener received text message: {}", message.getText());
+ }
+}
diff --git a/spring-jms/src/main/java/com/baeldung/spring/jms/testing/MessageSender.java b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/MessageSender.java
new file mode 100644
index 0000000000..6cb199b0e9
--- /dev/null
+++ b/spring-jms/src/main/java/com/baeldung/spring/jms/testing/MessageSender.java
@@ -0,0 +1,21 @@
+package com.baeldung.spring.jms.testing;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MessageSender {
+
+ @Autowired
+ private JmsTemplate jmsTemplate;
+
+ private static final Logger logger = LoggerFactory.getLogger(MessageSender.class);
+
+ public void sendTextMessage(String destination, String message) {
+ logger.info("Sending message to {} destination with text {}", destination, message);
+ jmsTemplate.send(destination, s -> s.createTextMessage(message));
+ }
+}
diff --git a/spring-jms/src/test/java/com/baeldung/spring/jms/testing/EmbeddedActiveMqIntegrationTest.java b/spring-jms/src/test/java/com/baeldung/spring/jms/testing/EmbeddedActiveMqIntegrationTest.java
new file mode 100644
index 0000000000..6644ee50ac
--- /dev/null
+++ b/spring-jms/src/test/java/com/baeldung/spring/jms/testing/EmbeddedActiveMqIntegrationTest.java
@@ -0,0 +1,91 @@
+package com.baeldung.spring.jms.testing;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.junit.EmbeddedActiveMQBroker;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jms.annotation.EnableJms;
+import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
+import org.springframework.jms.config.JmsListenerContainerFactory;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.spring.jms.testing.EmbeddedActiveMqIntegrationTest.TestConfiguration;
+
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = { TestConfiguration.class })
+public class EmbeddedActiveMqIntegrationTest {
+
+ @ClassRule
+ public static EmbeddedActiveMQBroker embeddedBroker = new EmbeddedActiveMQBroker();
+
+ @SpyBean
+ private MessageListener messageListener;
+
+ @SpyBean
+ private MessageSender messageSender;
+
+ @Test
+ public void whenListening_thenReceivingCorrectMessage() throws JMSException {
+ String queueName = "queue-1";
+ String messageText = "Test message";
+
+ embeddedBroker.pushMessage(queueName, messageText);
+ assertEquals(1, embeddedBroker.getMessageCount(queueName));
+
+ ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(TextMessage.class);
+
+ Mockito.verify(messageListener, Mockito.timeout(100))
+ .sampleJmsListenerMethod(messageCaptor.capture());
+
+ TextMessage receivedMessage = messageCaptor.getValue();
+ assertEquals(messageText, receivedMessage.getText());
+ }
+
+ @Test
+ public void whenSendingMessage_thenCorrectQueueAndMessageText() throws JMSException {
+ String queueName = "queue-2";
+ String messageText = "Test message";
+
+ messageSender.sendTextMessage(queueName, messageText);
+
+ assertEquals(1, embeddedBroker.getMessageCount(queueName));
+ TextMessage sentMessage = embeddedBroker.peekTextMessage(queueName);
+ assertEquals(messageText, sentMessage.getText());
+ }
+
+ @Configuration
+ @EnableJms
+ static class TestConfiguration {
+ @Bean
+ public JmsListenerContainerFactory> jmsListenerContainerFactory() {
+ DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
+ factory.setConnectionFactory(connectionFactory());
+ return factory;
+ }
+
+ @Bean
+ public ConnectionFactory connectionFactory() {
+ return new ActiveMQConnectionFactory(embeddedBroker.getVmURL());
+ }
+
+ @Bean
+ public JmsTemplate jmsTemplate() {
+ return new JmsTemplate(connectionFactory());
+ }
+ }
+
+}
diff --git a/spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqIntegrationTest.java b/spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqIntegrationTest.java
new file mode 100644
index 0000000000..d117b90423
--- /dev/null
+++ b/spring-jms/src/test/java/com/baeldung/spring/jms/testing/TestContainersActiveMqIntegrationTest.java
@@ -0,0 +1,101 @@
+package com.baeldung.spring.jms.testing;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.TextMessage;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.assertj.core.api.Assertions;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jms.annotation.EnableJms;
+import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
+import org.springframework.jms.config.JmsListenerContainerFactory;
+import org.springframework.jms.core.JmsTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.utility.DockerImageName;
+
+import com.baeldung.spring.jms.testing.TestContainersActiveMqIntegrationTest.TestConfiguration;
+
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = { TestConfiguration.class, MessageSender.class })
+public class TestContainersActiveMqIntegrationTest {
+
+ @ClassRule
+ public static GenericContainer> activeMqContainer = new GenericContainer<>(DockerImageName.parse("rmohr/activemq:5.14.3")).withExposedPorts(61616);
+
+ @SpyBean
+ private MessageListener messageListener;
+
+ @Autowired
+ private MessageSender messageSender;
+
+ @Autowired
+ private JmsTemplate jmsTemplate;
+
+ @Test
+ public void whenListening_thenReceivingCorrectMessage() throws JMSException {
+ String queueName = "queue-1";
+ String messageText = "Test message";
+
+ jmsTemplate.send(queueName, s -> s.createTextMessage(messageText));
+
+ ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(TextMessage.class);
+
+ Mockito.verify(messageListener, Mockito.timeout(100))
+ .sampleJmsListenerMethod(messageCaptor.capture());
+
+ TextMessage receivedMessage = messageCaptor.getValue();
+ assertEquals(messageText, receivedMessage.getText());
+ }
+
+ @Test
+ public void whenSendingMessage_thenCorrectQueueAndMessageText() throws JMSException {
+ String queueName = "queue-2";
+ String messageText = "Test message";
+
+ messageSender.sendTextMessage(queueName, messageText);
+
+ Message sentMessage = jmsTemplate.receive(queueName);
+ Assertions.assertThat(sentMessage)
+ .isInstanceOf(TextMessage.class);
+
+ assertEquals(messageText, ((TextMessage) sentMessage).getText());
+ }
+
+ @Configuration
+ @EnableJms
+ static class TestConfiguration {
+ @Bean
+ public JmsListenerContainerFactory> jmsListenerContainerFactory() {
+ DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
+ factory.setConnectionFactory(connectionFactory());
+ return factory;
+ }
+
+ @Bean
+ public ConnectionFactory connectionFactory() {
+ String brokerUrlFormat = "tcp://%s:%d";
+ String brokerUrl = String.format(brokerUrlFormat, activeMqContainer.getHost(), activeMqContainer.getFirstMappedPort());
+ return new ActiveMQConnectionFactory(brokerUrl);
+ }
+
+ @Bean
+ public JmsTemplate jmsTemplate() {
+ return new JmsTemplate(connectionFactory());
+ }
+ }
+
+}