There are probably several ways to achieve this. I will give the pair in the hope that you will work for you. ActorRef in mind that an IO(Tcp) call only creates an ActorRef . So all you have to do is find a way to mock / step in front of this call and then work with this ref actor. Here are some code examples showing a couple of solutions (sort of like a DI):
This first sets up a method to return the tcp manager and then overrides it in unit test.
class Actor1 extends Actor{ import context._ import Tcp._ def receive = { case "connect" => tcp ! Bind(self, new InetSocketAddress("localhost", 8080)) } def tcp:ActorRef = IO(Tcp) } class Actor1Spec(_system:ActorSystem) extends TestKit(_system) with Specification{ import Tcp._ def this() = this(ActorSystem("test")) trait scoping extends Scope{ val tcpProbe = TestProbe() val testRef = TestActorRef(new Actor1{ override def tcp = tcpProbe.ref }) } "A request to connect" should{ "send a message to connect to the Tcp Manager" in new scoping{ testRef ! "connect" tcpProbe.expectMsg(Bind(testRef, new InetSocketAddress("localhost", 8080))) } } }
This second one is very similar, but instead goes to the tcp manager in the constructor.
class Actor2(tcpManager:ActorRef) extends Actor{ import context._ import Tcp._ def receive = { case "connect" => tcpManager ! Bind(self, new InetSocketAddress("localhost", 8080)) } } class Actor2Spec(_system:ActorSystem) extends TestKit(_system) with Specification{ import Tcp._ def this() = this(ActorSystem("test")) trait scoping extends Scope{ val tcpProbe = TestProbe() val testRef = TestActorRef(new Actor2(tcpProbe.ref)) } "A request to connect" should{ "send a message to connect to the Tcp Manager" in new scoping{ testRef ! "connect" tcpProbe.expectMsg(Bind(testRef, new InetSocketAddress("localhost", 8080))) } } }
Any of these may work for you, but then again, there is no real magic if you understand that calling IO(Tcp) just returns an ActorRef
cmbaxter
source share