Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable JMS consuming bean in unit-test

I've build a Spring application that receives JMS messages (@JmsListener). During development I'd like to send some messages to the JMS-queue the listener listens to, so I wrote a unit-test that sends some messages (JmsTemplate). In this unit-test I use @SpringBootTest and @RunWith(SpringRunner.class) in order to load the application context (beans for datasources etc).

However, when the unit-test starts, it also loads the jms listener bean which directly starts consuming my new messages.

I would like to disable this jms listener bean in this test scenario so that messages are just added to the queue. Then later, I can start the main application and watch them being consumed.

How should I approach this?

I guess I could also have asked how I could disable a bean in general.

Thanks in advance.

like image 537
codesmith Avatar asked May 24 '17 06:05

codesmith


People also ask

How do I stop JMS listener?

You can access the JMS listener containers from the registry (all or by name) and call stop() on the one(s) you want; the container will stop after any in-process messages complete their processing.

How do you check if JMS listener is running?

The status of the listeners is always available by running the list listeners command from the user interface or the Transaction Server console. If a listener becomes disconnected, the Transaction Server can attempt to re-connect to the queue multiple times before it fails with a connection error.

What is JMS listener in spring boot?

The JmsListener annotation defines the name of the Destination that this method should listen to and the reference to the JmsListenerContainerFactory to use to create the underlying message listener container.


3 Answers

You could use profiles to solve this problem.

To your listener, add the @Profile annotation:

@Profile("!test-without-jmslistener")
public class JmsListenerBean {
    ...
}

This tells Spring that it should only create an instance of this bean if the profile "test-without-jmslistener" is not active (the exclamation mark negates the condition).

On your unit test class, you add the following annotation:

@ActiveProfiles("test-without-jmslistener)
public class MyTest {
    ...
}

Now the Spring test runner will activate this profile before running your tests, and Spring won't load your bean.

like image 94
Rolf Schäuble Avatar answered Oct 16 '22 15:10

Rolf Schäuble


Instead of using profiles you can also achieve this with a property:

@ConditionalOnProperty(name = "jms.enabled", matchIfMissing = true)
public class JmsListenerBean {
    ...
}

The matchIfMissing attribute tells Spring to set this property to true by default. In your test class you can now disable the JmsListenerBean:

@TestPropertySource(properties = "jms.enabled=false")
public class MyTest {
    ...
}
like image 2
kurt Avatar answered Oct 16 '22 15:10

kurt


Another solution to this problem: add @ComponentScan() to the test class to skip the loading of the specified beans.

@SpringBootTest
@RunWith(SpringRunner.class)
@ComponentScan(basePackages="com.pechen.demo", excludeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE, classes=JmsListener.class))
public class MyTest(){

}

Any more please refer to spring component scan include and exclude filters.

like image 1
Dave Pateral Avatar answered Oct 16 '22 14:10

Dave Pateral