Reputation: 121
I'm working on a Spring Boot project using RabbitMQ via Spring AMQP. We'd like to be able to test our app's behavior when a message publish is NACK'd (specifically when the ack
argument of PublisherConfirmCallback#confirm
is false
). However we're having a hard time trying to set up this scenario in an integration test (that is, with the app running, not a unit test).
Just to be clear, we're testing around publisher acknowledgements, not consumer acknowledgements.
We know you can get access to a channel with the RabbitTemplate's execute
method, but our RabbitMQ auto-acks, so the message is already gone by the time the channel callback is executed. We're thinking we might be able to either disable auto-ack at runtime (so as not to interrupt the test suite) or to simply block the channel and receive the message on it manually in the test, but we can't figure out how to do either of these. But really, any way to cause a NACK during a test would be great.
tl;dr how to nack a message from client code
Upvotes: 11
Views: 2034
Reputation: 98
The best way that I've discovered to test broker nacks when publishing messages is to set a queue max-length and set the overflow policy to reject-publish
. This causes the broker to nack
any messages once that max-length limit has been reached.
See the Rabbit docs.
The my-pol policy ensures that the two-messages queue contains no more than 2 messages and all additional publishes are sent basic.nack responses as long as the queue contains 2 messages and publisher confirms are enabled.
I was able to do this easily in the management console:
Note: as of RabbitMQ 3.13.6 this works with both classic and quorum queues.
Upvotes: 0
Reputation: 121
Publishing a message to a nonexistent exchange will cause the publisher confirm callback to receive a nack!
Upvotes: 1
Reputation: 72868
you will have to turn off auto-ack, to start with. with that turned on, it will not be possible to nack a message.
after that, you're test setup should include a message consumer that is coded specifically to do what you want, when you want... don't use your real code to test the nack handling. set up a consumer that only does a nack... or one that knows when it receives certain messages, it should nack
Upvotes: 0