Friday, February 27, 2015

Groovy closures and Awaitility are a match made in heaven

The awaitility pattern for waiting for a condition to be true has always irked me, it's always seemed like something that should be shorter and simpler. If you want to implement a wait in awaitility, you implement a callable interface and hand that off to awaitility to call repeatedly until its satisfied or times out. Giving you code that looks something like this …
Steps.java
@Then("a payload is sent to the destination")
public void aPayloadIsSentToTheDestination() throws Exception {
   PayloadIsSentChecker aPayloadIsSent = new PayloadIsSentChecker(acceptanceTestAmqpClient, Destination.EXAMPLE);
   await().atMost(FIVE_SECONDS).until(aPayloadIsSent);
}
PayloadIsSentChecker.java
public PayloadIsSentChecker(AcceptanceTestAmqpClient acceptanceTestAmqpClient, Destination destination) {
   this.acceptanceTestAmqpClient = acceptanceTestAmqpClient;
   this.destination = destination;
}

@Override
public Boolean call() throws Exception {
   Message message = acceptanceTestAmqpClient.lastMessageFromAcceptanceOutbound(destination);
   if (message == null) {
      return false;
   }
   return true;
}
However, if we bypass the callable interface entirely and use a groovy closure, with a mixin [AwaitilitySupport] from awaitility instead, we get
def thePayloadArrivesAt(Destination destination) {
   await().atMost(FIVE_SECONDS).until {
      assertThat(acceptanceTestAmqpClient.lastEventFromAcceptanceOutbound(destination), notNullValue())
   }
}
And voila, a significant reduction in boiler plate code.

No comments: