codesmith
codesmith

Reputation: 1431

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.

Upvotes: 10

Views: 5068

Answers (4)

kurt
kurt

Reputation: 21

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 {
    ...
}

Upvotes: 2

Prabin
Prabin

Reputation: 29

I think you can do it by this code:-

private void stopJMSListener() {
    if (customRegistry == null) {
        customRegistry = context.getBean(JmsListenerEndpointRegistry.class);
    }
    customRegistry.stop();
}

private void startJMSListener() {
    if (customRegistry == null) {
        customRegistry = context.getBean(JmsListenerEndpointRegistry.class);
    }
    customRegistry.start();
}

Upvotes: 0

Dave Pateral
Dave Pateral

Reputation: 1475

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.

Upvotes: 1

Rolf Schäuble
Rolf Schäuble

Reputation: 690

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.

Upvotes: 8

Related Questions