Skip to content

An extension to JUnit/Hamcrest providing assertions with tolerance, featuring a retry mechanism.

License

Notifications You must be signed in to change notification settings

alb-i986/assert-retry

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Assert Retry

An extension to JUnit/Hamcrest providing assertions with tolerance, featuring a retry mechanism.

Motivation

AFAIK there are already two libraries out there resolving the same problem this library is addressing:

Awaitility in particular looks pretty good indeed.

The added value of assert-retry is that it is integrated with Hamcrest's assertThat assertions.

What I love about Hamcrest assertions is the valuable feedback they provide to the user when they fail.

Example of usage

Say that we have a JMS queue, and we need to verify that a message with body "expected content" is published on the queue. Given the async nature of the system, we need to employ a bit of tolerance in our assertions.

import static me.alb_i986.testing.assertions.retry.RetryMatcher.eventually;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
  
MessageConsumer consumer = session.createConsumer(queue);
connection.start();
Supplier<String> messageText = new Supplier<>() {
    @Override
    public String get() throws JMSException {
        TextMessage m = (TextMessage) consumer.receiveNoWait();  // polling for messages, non blocking
        return m == null ? null : m.getText();
    }
};
assertThat(messageText, eventually(containsString("expected content"),
        RetryConfig.builder()
            .timeoutAfter(Duration.ofSeconds(60))
            .sleepFor(Duration.ofSeconds(5))
            .retryOnException(JMSException.class)
));

The first few lines set up the Supplier of actual values, which will poll the message queue for messages.

Then we have our assertion. In this example it is asserting that the expected text message will be received within 60 seconds. After each failing attempt, it will wait for 5s, and then it will try again.

If consumer.receiveNoWait() throws a JMSException, the assertion will be re-tried, as if it returned a non-matching value.

Finally, the assertion will timeout after 60s, and an AssertionError similar to the following will be thrown:

   java.lang.AssertionError:
   Expected: supplied value to *eventually* match a string containing "expected content" within 60s
       but: The timeout was reached and none of the actual values matched
            Actual values (in order of appearance):
             - "some content"
             - thrown javax.jms.MessageFormatException: Blah blah
             - "some other content"

For more info, please check the javadoc of RetryMatcher#eventually.

About

An extension to JUnit/Hamcrest providing assertions with tolerance, featuring a retry mechanism.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages