I had a chance to look over the typed actors a bit more.  Here is my 
feedback.  Whether you agree or disagree, I hope you find it useful.  I am 
still really excited about typed actors, the main reason I have been 
reluctant to switch to akka is that I was not willing to give up static 
typing.  

Behavior by itself is easy to test as long as you are not doing anything 
with ActorContext.  I particularly like the separation of the management 
method to deal with lifecycle signals, from the message method to deal with 
messages.

ActorContext can't be stubbed out because it leaks out the private classes 
InternalActorRef and ActorSystemImpl through its protected methods 
lookupRoot, guardian, and systemImpl.

ActorRef can't be stubbed out because of the self type on 
internal.ActorRefImpl.  I have already demonstrated issue with this in 
detail with my FooApp and BarApp examples in this thread.  I did look up 
the ScalaDoc for ActorRefImpl, and while I think its fine to hide the 
sendSystem and isLocal methods, I do think that if these methods were 
pushed down into a class that inherits from ActorRef, rather than using a 
self type, that would make it easier to stub out ActorRef.

ActorSystem has the same problem as ActorRef for the same reason, but it 
manifests much worse because the ActorSystem trait has so many more 
methods.  To see why, consider writing a unit test to make sure an actor 
system is properly shut down once the program is finished.  I want to test 
the code here:
https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/main/scala/com/seanshubin/concurrency/samples/actor/CleanupActorSystems.scala
It should be as easy as this:
https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/test/scala/com/seanshubin/concurrency/samples/actor/CleanupActorSystemsTest.scala
And from looking at this test it seems like it is, but look what I had to 
do to get to this point:
On my dependency injection class I had to add another level of indirection
  val eventActorSystem: ActorSystem[Event] = ActorSystem("state", stateful)
  val eventActorSystemContract: ActorSystemContract[Event] = 
    new ActorSystemDelegate[Event](eventActorSystem)
I had to hide ActorSystem behind an interface
https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/main/scala/com/seanshubin/concurrency/samples/actor/ActorSystemContract.scala
And then delegate to the real ActorSystem
https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/main/scala/com/seanshubin/concurrency/samples/actor/ActorSystemDelegate.scala
That way, for testing I could start with a class where nothing is 
implemented:
https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/test/scala/com/seanshubin/concurrency/samples/actor/ActorSystemNotImplemented.scala
Then use that not implemented class as a base for my stub
  class ActorSystemStub extends ActorSystemNotImplemented[Event] {
    var terminateInvocationCount = 0

    override def terminate(): Future[Terminated] = {
      terminateInvocationCount += 1
      null
    }
  }
Which I finally use in my test
https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/test/scala/com/seanshubin/concurrency/samples/actor/CleanupActorSystemsTest.scala

My impression is that most of these problems stem from exposing classes to 
the user that are too concrete.  If we could push some of these 
implementation details like private clases and self types further down the 
inheritance chain, and remove the need for client code to have a compile 
time dependency on the implementation details, it would be much easier to 
stub out interactions and have fully unit-tested code.

-- 
>>>>>>>>>>      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+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to