I'm testing an actor that makes direct calls to an API that returns futures. Upon completion of a future, the actor uses the pipe pattern to send a message to itself in order to avoid concurrent mutation of its state:
import akka.pattern.pipe
// ...
// somewhere in the actor's receive method
futureBasedApi.doSomething().pipeTo(self)
In my test I mock the API in a way that lets me control when the futures are completed via promises. However, this is interleaved with other messages sent directly to the actor:
myActor ! Message("A")
promiseFromApiCall.success(Message("B"))
myActor ! Message("C")
Now I'm wondering how I can guarantee that the actor receives and processes message B between message A and C. I'm not even completely sure that message B is guaranteed to reach the actor's mailbox after A. At least from my current understanding, sending a message to an actor is a fire-and-forget operation and there is no guarantee the message will ever arrive. This is unlikely if my actor is in the same JVM as the test but I'm not sure whether the message is acutally guaranteed to be in the actor's mailbox when the tell-call (!) returns.
The root of the problem is that message B is actually sent in another thread. The only thing I know for sure is that this happens after my test sent message A and before it sends message C but I can't control the order that actor's mailbox receives the messages.
I thought about several possible solutions:
-
sleep after each message for a few milliseconds to make another order very unlikely
-
wait for the actor to acknowledge each message, although acknowledgement is only required for testing
-
send message B directly to the actor to simulate completion of the future and write a separate test that ensures that the pipe pattern is properly used (the test above would not fail if the actor would not pipe the result message to itself)
I don't really like either of these options but I tend to use the last one.
Is my understanding of the problem correct and is there another better way I can solve it?
Aucun commentaire:
Enregistrer un commentaire