Re: [akka-user] Testing messages to self

662 views
Skip to first unread message

Roland Kuhn

unread,
Jan 2, 2013, 2:36:56 PM1/2/13
to akka...@googlegroups.com
Hi Paolo,

2 jan 2013 kl. 16:06 skrev Paolo Di Tommaso:

Dear all, 

Reading the documentation I was unable to find a way to test for messages that an actor send to itself. 

Using the (Java)TestKit is quite easy to expect for messages that an actor send to someone else, but how to check for a message that an actor can send to itself ?

Messages sent to `self` are unobservable to the outside—unless they have some verifiable effect without which they would be pointless. If verifying the effect is somehow impractical then the closest I can think of is to create a SnitchMailbox which secretly keeps copies of all enqueued messages for later inspection. While trivial to do yourself—see the PeekMailbox in 2.1.0’s contrib area—I’m not sure whether it would be a good idea to ship such a thing as part of the official package …

Regards,


Dr. Roland Kuhn
Akka Tech Lead
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn

Paolo Di Tommaso

unread,
Jan 3, 2013, 8:18:57 AM1/3/13
to akka...@googlegroups.com
Hi Roland, 

I gave a try to PeekMailbox, but this would require to rewrite all the logic to mimic the methods expectMsgXxx which are pretty useful, too much work!. 

I solved overriding dynamically the actor getSelf() method retuning a new JavaTestKit.getRef() instance. This does the trick. 


Anyway in my opinion it is really a pity that this condition is not managed by the TestActorRef by default. There are many use case in which it is useful to test for messages against the self actor. 


Cheers,
Paolo

Derek Wyatt

unread,
Jan 3, 2013, 8:34:26 AM1/3/13
to akka...@googlegroups.com
On 2013-01-03, at 8:18 AM, Paolo Di Tommaso wrote:
Hi Roland, 

I gave a try to PeekMailbox, but this would require to rewrite all the logic to mimic the methods expectMsgXxx which are pretty useful, too much work!. 

I solved overriding dynamically the actor getSelf() method retuning a new JavaTestKit.getRef() instance. This does the trick. 

Anyway in my opinion it is really a pity that this condition is not managed by the TestActorRef by default. There are many use case in which it is useful to test for messages against the self actor. 

TL;DR -- don't just toss aside the paradigm that you've been given - think hard about the facilities that are in place before thinking you need to do something else.

I don't agree.  I also think that you might be missing part of the Actor paradigm in this case.  What good does it do to see that an Actor sent a message to itself?  You need to validate that a particular change has occurred, which resulted from that message, not that the message was queued.

A slightly laboured analogy would be:

def someMethod = {
  val x = // some calculation
  val y = // some calculation based on x
  y map { // do something here }
}

And you want to verify that 'x' was calculated as some value.  Who cares?  And if, indeed, you do care, then you need to factor that code out into its own function and test that function.

You seem to be saying that you don't care to know what the effect of the self-message pass is in your app, but you do care in your test.  That's weird.  Eventually, the result of the self-message pass should be seen as an effect in your app, and it's that which you should be validating, not that the message was sent / received.

Regs,
Derek



Cheers,
Paolo



On Wed, Jan 2, 2013 at 8:36 PM, Roland Kuhn <goo...@rkuhn.info> wrote:
Hi Paolo,

2 jan 2013 kl. 16:06 skrev Paolo Di Tommaso:

Dear all, 

Reading the documentation I was unable to find a way to test for messages that an actor send to itself. 

Using the (Java)TestKit is quite easy to expect for messages that an actor send to someone else, but how to check for a message that an actor can send to itself ?

Messages sent to `self` are unobservable to the outside—unless they have some verifiable effect without which they would be pointless. If verifying the effect is somehow impractical then the closest I can think of is to create a SnitchMailbox which secretly keeps copies of all enqueued messages for later inspection. While trivial to do yourself—see the PeekMailbox in 2.1.0’s contrib area—I’m not sure whether it would be a good idea to ship such a thing as part of the official package …

Regards,


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> 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 post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user?hl=en.
 
 

Akka Team

unread,
Jan 3, 2013, 8:56:05 AM1/3/13
to akka...@googlegroups.com
Chorus: Amen, brother!
--
Akka Team
Typesafe - The software stack for applications that scale
Blog: letitcrash.com
Twitter: @akkateam

Paolo Di Tommaso

unread,
Jan 4, 2013, 9:53:38 AM1/4/13
to akka...@googlegroups.com
Hi Derek, 


I think that Akka is really an excellent framework and I take your work really seriously. I'm new to Akka so I'm really interested to learn as much as possible about it, but in this case I think we have two different points of view. 

Let me explain better my test case. Generally you can see an actor as a black box, when it receives a message, it will change its state and eventually it will send some other message(s) as consequence of the input event. 

So, what a test does for a particular message is to check the actor state changed as expected, and that the messages to other actors have been sent. Right? OK. 

In my case I have an actor, let say A, that when receives a message, call it m1, does some stuff and replies to another actor B with the message b1, or to itself with a message m2 when a particular condition is met. 

My test for message m1 validate that the A state has changed as expected - AND - that the message b1 or m2 has been sent, depending the underlying business logic. 

I don't want to check for the state update applied by m2 to A, since I have a separate test for it, as well as I have another test for message b2 to B. 

This does not seem so strange to me, indeed it appears to be more coherent with the fact that you do not care about the state updated for outgoing messages, regardless it is a message to another actor or to itself.


Just my 2 cents. 

Cheers,
Paolo



  



On Thu, Jan 3, 2013 at 2:34 PM, Derek Wyatt <de...@derekwyatt.org> wrote:

Roland Kuhn

unread,
Jan 4, 2013, 10:16:51 AM1/4/13
to akka...@googlegroups.com
Hi Paolo,

4 jan 2013 kl. 15:53 skrev Paolo Di Tommaso:

I think that Akka is really an excellent framework and I take your work really seriously. I'm new to Akka so I'm really interested to learn as much as possible about it, but in this case I think we have two different points of view. 

Let me explain better my test case. Generally you can see an actor as a black box, when it receives a message, it will change its state and eventually it will send some other message(s) as consequence of the input event. 

So, what a test does for a particular message is to check the actor state changed as expected, and that the messages to other actors have been sent. Right?

The difference in view is exactly here, hence the answer is «no»: tests within the actor model do not verify internal state changes of actors, they only verify messages produced in response to the test stimulus. A message sent to “self” is not produced in that sense, since nobody can observe it outside of the actor.

A message sent to some Consumer can be verified by injecting a TestConsumer. And if that consumer in the normal case would by chance be the actor itself, then that would work, too (i.e. you would normally have a SelfConsumer mixed in and would replace that in the test with an external TestConsumer). But that only makes sense if the messages sent to that Consumer are meaningful outside of the actor, otherwise they are just an internal implementation detail.

Having said that, I can understand where you are coming from: unit tests in the traditional sense tend to verify implementation details, and that is a lot more difficult with actors; TestActorRef helps a lot here, but at the intersection of sequential code and message passing you encounter difficulties. But keep in mind that those tests which are most useful—especially later when evolving your codebase—are functional tests, i.e. tests which do not depend on the implementation details at all. They are usually harder to write, but they verify what you actually want to prove. Unit tests can then complement those higher-level tests, but they are mostly useful for determining the cause of other test failures, plus they tend to see a lot of churn due to changes in the implementation.

Does this help?

Regards,

Roland

Paolo Di Tommaso

unread,
Jan 4, 2013, 10:55:52 AM1/4/13
to akka...@googlegroups.com
Hi Roland, this clarify a lot. 


Thanks, 
Paolo
Reply all
Reply to author
Forward
0 new messages