I'm trying to create integration tests for a MessageListener that is processing messages from a SQS queue. One of the test cases I would like to verify is that an improperly formatted message sent to the MessageListener ends up in the Dead Letter Queue (also an SQS queue) that has been setup in the AWS console.
I'm having difficulty figuring out how to test this though, as you cannot search the Dead Letter Queue queue for a specific message id (i.e. see if it contains a message) without sifting through all the messages. My initial thought was to poll the dead letter queue and verify that the message id exists in there but it seems like that will have some problems. The integration test will send a message to the actual queue in our testing environment, so there may be an unknown number of other messages already present in the dead letter queue (and the messages in the dead letter queue could be continuously increasing). I also tried using some of the properties associated with a JMS message, but it seems like they aren't updated in my local instance of the message when the message goes from the test -> SQS queue -> MessageListener. Any ideas on how to test this scenario?
Here's an example of how the MessageListener is setup:
public class ExampleMessageListener implements MessageListener {
@Override
public void onMessage(final Message message) {
// message handling logic
// if something goes wrong in message handling logic message won't be acknowledged
// and should end up in the DLQ
message.acknowledge()
}
}
How I'm sending the message to the queue the MessageListener is consuming in my integration test:
SQSConnectionFactory connectionFactory = new SQSConnectionFactory(
new ProviderConfiguration(),
AmazonSQSClientBuilder.standard()
.withRegion(config.getRegion().getName())
.withCredentials(config.getCredentialsProvider())
);
SQSConnection connection = connectionFactory.createConnection();
session = connection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE);
final Queue queue = session.createQueue("SQS-queue-name");
this.messageProducer = session.createProducer(queue);
final TextMessage textMessage = session.createTextMessage("improper message");
messageProducer.send(textMessage);
One additional note: There's a database that the MessageListener is modifying, and I'm able to use that to check if the properly formatted messages are changing data as expected. Improperly formatted messages don't end up interacting with this database though.
Keep in mind that Amazon SQS doesn't support message selectors via their JMS client implementation.