@Test
public void deliverMessageTest() {

    ShadowApplication application = ShadowApplication.getInstance();
    ServiceActorThread thread = new ServiceActorThread(application.getApplicationContext(), mProxyFactory,
            mFailureHandler, ActorService.class, 1);
    ActorRef<Runnable> ref = thread.bind(Runnable.class, mActorImpl);
    Assert.assertSame(mProxy, ref.tell());
    ArgumentCaptor<MessageSender> postmanCaptor = ArgumentCaptor.forClass(MessageSender.class);
    Mockito.verify(mProxyFactory).newProxy(Mockito.<Class>any(), postmanCaptor.capture());
    MessageSender postman = postmanCaptor.getValue();
    Assert.assertNotNull(postman);
    // Should try to start service
    Mockito.doReturn(true).when(mMessageSender).deliver(Mockito.any(Transaction.class));
    Message message = Mockito.mock(Message.class);
    postman.deliver(message);
    Intent intent = application.getNextStartedService();
    Assert.assertNotNull(intent);
    Assert.assertEquals(new ComponentName(application.getApplicationContext(), ActorService.class),
            intent.getComponent());
    ArgumentCaptor<Transaction> captor = ArgumentCaptor.forClass(Transaction.class);
    Mockito.verify(mMessageSender).deliver(captor.capture());
    Transaction transaction = captor.getValue();
    Assert.assertNotNull(transaction);
    Assert.assertSame(mActorImpl, transaction.impl);
    Assert.assertSame(mFailureHandler, transaction.failureHandler);
    Assert.assertSame(message, transaction.message);
    // Now we bound, but sender will not accept transactions, so we should try to bind again
    Mockito.reset(mMessageSender);
    Mockito.doReturn(mBinder).when(mMessageSender).asBinder();
    Mockito.doReturn(false).when(mMessageSender).deliver(Mockito.any(Transaction.class));
    application.clearStartedServices();
    message = Mockito.mock(Message.class);
    postman.deliver(message);
    intent = application.getNextStartedService();
    Assert.assertNotNull(intent);
    Assert.assertEquals(new ComponentName(application.getApplicationContext(), ActorService.class),
            intent.getComponent());
    captor = ArgumentCaptor.forClass(Transaction.class);
    // Should be two invocation, one when we tried bound one and another after rebinding
    Mockito.verify(mMessageSender, Mockito.times(2)).deliver(captor.capture());
    transaction = captor.getValue();
    Assert.assertNotNull(transaction);
    Assert.assertSame(mActorImpl, transaction.impl);
    Assert.assertSame(mFailureHandler, transaction.failureHandler);
    Assert.assertSame(message, transaction.message);
    // Next one shouldn't try to start service - just do direct call
    Mockito.reset(mMessageSender);
    Mockito.doReturn(mBinder).when(mMessageSender).asBinder();
    Mockito.doReturn(true).when(mMessageSender).deliver(Mockito.<Transaction>any());
    application.clearStartedServices();
    message = Mockito.mock(Message.class);
    postman.deliver(message);
    Assert.assertNull(application.getNextStartedService());
    Mockito.verify(mMessageSender).deliver(captor.capture());
    transaction = captor.getValue();
    Assert.assertNotNull(transaction);
    Assert.assertSame(mActorImpl, transaction.impl);
    Assert.assertSame(mFailureHandler, transaction.failureHandler);
    Assert.assertSame(message, transaction.message);
    // Ok, now unbind and try again. We should start service
    ((ServiceConnection) postman).onServiceDisconnected(null);
    Mockito.reset(mMessageSender);
    Mockito.doReturn(mBinder).when(mMessageSender).asBinder();
    application.clearStartedServices();
    message = Mockito.mock(Message.class);
    postman.deliver(message);
    intent = application.getNextStartedService();
    Assert.assertNotNull(intent);
    Assert.assertEquals(new ComponentName(application.getApplicationContext(), ActorService.class),
            intent.getComponent());
    captor = ArgumentCaptor.forClass(Transaction.class);
    Mockito.verify(mMessageSender).deliver(captor.capture());
    transaction = captor.getValue();
    Assert.assertNotNull(transaction);
    Assert.assertSame(mActorImpl, transaction.impl);
    Assert.assertSame(mFailureHandler, transaction.failureHandler);
    Assert.assertSame(message, transaction.message);
}