Java : How should Futures be handled when Unit testing?

1,973 views
Skip to first unread message

Adam Daines

unread,
Apr 9, 2015, 7:30:36 AM4/9/15
to akka...@googlegroups.com
Hi all,

I've got a question in relation to the unit testing of a piece of non actor code that produces a Future<ActorRef> via performing an actorSelection().resolveOne on the ActorSystem.

Within the Future.onFailure() a value is being set that I would like to test but the Future is making use of the ActorSystem.dispatcher() which is therefore causing asynchronicity issues when attempting to Assert that the value has been set as expected.

I am currently performing a Thread.sleep() within the Unit test to provide enough time for the value to have been set but this is far from ideal! 

What is the best way to go about testing this type of code without having to sleep and wait? Is it possible to override the dispatcher that the ActorSystem returns with the CallingThreadDispatcher?

Thanks.

Viktor Klang

unread,
Apr 9, 2015, 7:33:48 AM4/9/15
to Akka User List

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.



--
Cheers,

Akka Team

unread,
Apr 9, 2015, 7:59:28 AM4/9/15
to Akka User List
That is for scala though. We usually use scala.concurrent.Await which can be used like this

  assert(Await.result(myFuture, timeoutDuration) == xyz)

This will block the test and wait until the future becomes ready. If the future completes then the assertion will run. If the future fails, then Await.result() will throw the exception. If the future does not complete during the time defined in timeoutDuration, then it will throw A TimeoutException.

-Endre



--
Akka Team
Typesafe - Reactive apps on the JVM
Blog: letitcrash.com
Twitter: @akkateam

Viktor Klang

unread,
Apr 9, 2015, 8:01:24 AM4/9/15
to Akka User List
Ouch, nice catch, now we've covered both the question and the alternative (Scala) :)

Adam Daines

unread,
Apr 9, 2015, 8:46:22 AM4/9/15
to akka...@googlegroups.com
Thank you both for the quick and helpful responses! 
Our issue is now resolved :)

Thanks.

Adam Daines

unread,
Apr 9, 2015, 10:22:43 AM4/9/15
to akka...@googlegroups.com
Hi again, 

At first it had appeared that the issue was fully resolved but the test I had written began to fail again intermittently.  
It appears that taking the approach Endre suggested does not quite work as I had expected. It appears that the Await triggers and unblocks at the moment that the Future gets completed which is before the .onSuccess & .onFailure have actually run. 

In my use case the variable (which is a deferredResult) is actually set inside the .onFailure, therefore I cannot do an assertion on it until after the .onFailure has finished running.

Any further assistance would be much appreciated.

Thanks.

Viktor Klang

unread,
Apr 9, 2015, 10:27:38 AM4/9/15
to Akka User List
Hi Adam,

I generally recommend against using onComplete, onSuccess and onFailure for that reason,
instead use map/flatMap/andThen/recover/recoverWith/transform
Reply all
Reply to author
Forward
0 new messages