Akka TestKit (Java), I want to only consume/expect message object which has some specific string?

120 Views Asked by At

I have an Actor, which publish different kind of messages at different events and junit has been written for that using TestKit.

I want to consume message with "specific word" only and skip the rest. Below code consumes all the message but I want to check all and only consume message with specific word, rest to ignore.

while (testKit.msgAvailable()) {
      testKit.expectMsgClass(Message.class);
    }

How I may do? I could see a method "fishForSpecificMessage()" but not getting how I could do compare the string at Function parameter or provide the implementation for it.

https://doc.akka.io/japi/akka/current/akka/testkit/javadsl/TestKit.html#fishForSpecificMessage(java.time.Duration,java.lang.String,java.util.function.Function)

Please help with some example.

2

There are 2 best solutions below

0
On

The Java API for fishForSpecificMethod appears basically broken: it makes sense in the Scala API, where it takes a partial function, but since the Java API takes a total function, the underlying implementation (which is the Scala API) prevents the Java API from meeting its contract.

In Java, the most natural thing is probably going to be along the lines of

testKit.within(
  testKit.getRemainingOrDefault(),
  () -> {
    while (true) {
      Object msg = testkit.receiveOne(testKit.getRemaining());
      assertNotNull(msg, "Timeout of " + maxTimeout + " fired");
      // test message for matching predicate, if matching, return msg cast to the appropriate class, otherwise continue to the next iteration
    }
    return null; // possibly pro forma to satisfy typechecker...
  }
)
0
On

I already successfully used fishForMessage to do so, e.g.:

final ResourceStatus actualStatus = (ResourceStatus) testKit.fishForMessage(
  Duration.ofSeconds(1), 
  "My hint", 
  o -> o instanceof ResourceStatus rs && 
       rs.getResourceType() == ResourceStatus.ResourceType.CLIENT
);
assertThat(actualStatus.getRecoveryStatus()).contains(expectedRecoveryStatus);