11

I want to write test for something like below;

  1. There is a listener called state-info-1 in src/main.

  2. It does some changes to any message it gets and publishes the new message on activemq topic state-info-2.

  3. I will build a dummy message and publish on to activemq topic state-info-1.

  4. Finally verify that, the received message on topic state-info-2 is like i expected.

My Listeners are like;

@JmsListener(destination = "state-info-1", containerFactory = "connFactory")
public void receiveMessage(Message payload) {
    // Do Stuff and Publish to state-info-2
}

Is it possible i can write test for this? Or i have to do it in some other way?

Also, i looked at this : https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-activemq/src/test/java/sample/activemq/SampleActiveMqTests.java

But this is not what i am expecting.

Any help or push in the right direction will be enough.

Thank you for your time.

Rajkishan Swami
  • 3,569
  • 10
  • 48
  • 68

1 Answers1

15
@SpringBootApplication
public class So42803627Application {

    public static void main(String[] args) {
        SpringApplication.run(So42803627Application.class, args);
    }

    @Autowired
    private JmsTemplate jmsTemplate;

    @JmsListener(destination = "foo")
    public void handle(String in) {
        this.jmsTemplate.convertAndSend("bar", in.toUpperCase());
    }

}

and

@RunWith(SpringRunner.class)
@SpringBootTest
public class So42803627ApplicationTests {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Test
    public void test() {
        this.jmsTemplate.convertAndSend("foo", "Hello, world!");
        this.jmsTemplate.setReceiveTimeout(10_000);
        assertThat(this.jmsTemplate.receiveAndConvert("bar")).isEqualTo("HELLO, WORLD!");
    }

}
oberlies
  • 11,503
  • 4
  • 63
  • 110
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • 1
    thanks. While this works for `Queues`, does not work for activemq `Topics` which i use. Does not work when i have properties `spring.jms.pub-sub-domain=true`. Gets `null`. – Rajkishan Swami Mar 17 '17 at 07:58
  • 3
    That's just the way JMS topics work - by default, subscriptions are not durable and only those consumers that are active at the time the message is published get the message. You either need to wait for the listener to subscribe before sending, or make the subscription durable (which means you only have to wait the first time you run the test). – Gary Russell Mar 17 '17 at 12:53
  • got it! Made it wait and it works fine. Thanks again :) – Rajkishan Swami Mar 20 '17 at 05:40
  • My use case involves a single consumer that does not reply, is there a way to verify that the message is received without the consumer sending a reply via the JmsTemplate class? – Lucas May 22 '18 at 18:59
  • 1
    It's generally best to ask a new question rather than commenting on an old one [this answer](https://stackoverflow.com/questions/50214261/unable-to-unit-test-a-kafkalistener-annotated-method/50219126#50219126) describes a technique we implemented for `@RabbitListener` and explains how it can be implemented for `@KafkaListener`. The same techniques should apply to JMS too via a custom `JmsListenerAnnotationBeanPostProcessor`. – Gary Russell May 22 '18 at 21:00
  • 2
    For **JUnit 5** replace the `RunWith` rule, with extension `@ExtendWith(SpringExtension.class)` (and exclude the junit4 dep from org.springframework.boot:spring-boot-starter-test) – earcam Aug 02 '18 at 00:38