Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable Spring SQS handler in module/integration test

I have a spring boot application that does not much more than listening to an SQS queue via a component "MessageHandler" that has a @SqsListener-annotated method, and start some work when a message arrives.

There is also a boot-starter-web dependency, since we want to fetch health status and metrics via http in production.

Now I wanted to write a module test, that already has an application context and autowires beans. I also found out how to disable the web server that is not needed by the test:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE)

However, the MessageHandler bean also gets instantiated and tries to connect to AWS, which I'd like to prevent.

One solution that works is to have a test implementation in src/test/java with @Primary annotation, whose handleMessage method does NOT have the @SqsListener annotation:

@Component
@Primary
public class TestMessageHandler implements MessageHandler {

    @Override
    public void handleMessage(final NewMessage newMessage) throws Exception {
        return null;
    }
}

But now I'd like to also test the (real) MessageHandler bean, meaning, I'd like Spring to instantiate it and autowire it's dependencies, but I still don't want the @SqsListener annotations to become active, so I can invoke it like this in my test:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE)
public class IntegrationTest {

    @Autowired
    private RealMessageHandler messageHandler;


    @Test
    public void testHandleMessage() throws Exception {
        messageHandler.handleMessage(new NewMessage(...));
    }
}

So what I need is to switch off the magic from the spring-cloud-aws-starter module that sets up the SQS listener for the handleMessage method in the RealMessageHandler.

Any clue how I would do that?

like image 806
Bernhard Avatar asked May 18 '17 07:05

Bernhard


Video Answer


1 Answers

I had a similar issue and resolved it by mocking the SimpleMessageListenerContainer bean. I plan to do this for multiple integration tests so to those tests more readable I've created a @TestConfiguration class which I then import in the test.

This is my configuration class:


/**
 * Configuration class for integration test that do not need message listening capabilities.
 */
@TestConfiguration
public class MockMessageListenerConfiguration {

  @MockBean
  private SimpleMessageListenerContainer messageListenerContainer;

}

And I use it like this:

@SpringBootTest
@Import({MockMessageListenerConfiguration.class})
class BookingRepositoryIT {...}

After this, the connection refused warnings related to AWS SQS disappeared.

like image 51
BitfullByte Avatar answered Oct 18 '22 17:10

BitfullByte