dimanche 26 juin 2016

How to test composition of futures inside a receive method of actor?

I have the following actor code:

class MyActor @Inject()(dao1: MyDao, dao2: OtherDao, eventBus: EventBus) extends Actor with ActorLogging {

  import context.dispatcher
  eventBus.subscribe(context.self, MyTopics.FooTopic)

  override def receive: Receive = {
    case Foo(name: String) => {
        dao.get(name)
          .flatMap(result => dao2.getSomeMoreStuff(result)
              .flatMap( data => //do more stuff)
          )
    }
  }
}

When the actor finish to process Foo, it will invoke this future composition, and will move to process another Foo message, before this composition is finished, which is ok (I think).

My problem is testing this actor:

class MyActorTest(_system: ActorSystem) extends TestKit(_system)
with WordSpecLike with Matchers with BeforeAndAfterAll
with MockitoSugar with DefaultTimeout with ImplicitSender{

  def this() = this(ActorSystem("myActorSpec"))

  override def afterAll {
    TestKit.shutdownActorSystem(system)
  }

  trait MyActorScope extends Scope {
    val myDao = mock[MyDao]
    val otherDao = mock[OtherDao]
    val eventBus = new MyEventBus()
    val myActor = TestActorRef(new MyActor(myDao, otherDao, eventBus)
  }

  "Test" must {
    "verify dao" in new EmployeeAssignToPoliciesActorScope {
        when(myDao.get(any)).thenReturn(Future.successful(("myDaoResult")))
        when(otherDao.getSomeMoreStuff(any)).thenReturn(Future.successful(("otherDaoResult")))
        eventBus.publish(new FooMessage(FooPayload("foo")))
        verify(myDao).get(any)
        verify(otherDao).getSomeMoreStuff(any)
     }
   }
}

So what happens here, is that myDao is verified successfully but the other Dao isn't. I think it's because the composition of the futures did not happened before the end of this message processing.

Any way to handle this? Does the actor code make sense?

Thanks!

Aucun commentaire:

Enregistrer un commentaire