Hi all, I'm trying to build up a decent parent-child pattern. I'm testing using Akka-Testkit.
The simplification follows:
import reflect.ClassManifest
class Parent[T <: Child : ClassManifest] extends Actor {
val child = context.actorOf(Props[T])
def receive = {
case 'pong => println("got pong")
case 'ping_child => child ! 'ping
case a => println(a)
}
}
class Child extends Actor {
def receive = {
case 'ping => context.parent ! 'pong
case a => println(a)
}
}
Is there a way in which I can test the Child, in isolation, using TestKit?
I've tried a lot of things, but can't seem to get messages to the testActor.
Best Regards,
Bryan Hunt--
>>>>>>>>>> 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.
Thanks Roland, that trick is rather handy.
Perhaps the TestKit maintainers could add a similar method to the API.
I'm pasting in the full example so that it may be useful to anyone doing something similar.
import akka.actor._
import akka.actor.FSM
import akka.testkit._
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
class ChildParentFSMTest extends TestKit(_system = ActorSystem()) with Specification with Mockito with DefaultTimeout with ImplicitSender {
// FTP States
sealed trait FTPState
case object FTPUninitialized extends FTPState
case object FTPIdle extends FTPState
case object FTPSyncing extends FTPState
// FTP Events
sealed trait FTPEvent
case class FTPDoInit(conf: FTPConf) extends FTPEvent
// FTP Data
sealed trait FTPData
case object FTPNone extends FTPData
case class FTPInitialized(downloader: FTPDownloader, conf: FTPConf) extends FTPData
case class FTPSynced(downloader: FTPDownloader, conf: FTPConf, newFiles: Option[List[_]] = None,
oldFiles: Option[List[_]] = None) extends FTPData
class FTPConf(val remoteDir: String = "/") {}
class FTPDownloader(val conf: FTPConf) {
def open() = ()
def changeDir(s: String) = ()
}
"FTPFetcher should " in {
"Verify Parent - Child communications" in {
class FTPFsm extends Actor with FSM[FTPState, FTPData] {
startWith(FTPUninitialized, FTPNone)
when(FTPUninitialized) {
case Event(FTPDoInit(c), FTPNone) => {
println("FTPDoInit")
goto(FTPIdle) using FTPInitialized(new FTPDownloader(c), c)
}
}
when(FTPIdle) {
case Event('checkfiles, input@FTPInitialized(ftp, c)) => goto(FTPIdle) using input
}
onTransition {
case FTPUninitialized -> FTPIdle =>
stateData match {
case _ => {
print("replying!")
context.parent ! 'connected
}
}
}
}
val p = system.actorOf(Props(new Actor {
val child = context.actorOf(Props(new FTPFsm), "child")
def receive = {
case x if sender == child => testActor forward x
case x => child forward x
}
}))
p ! FTPDoInit(new FTPConf)
p ! 'checkfiles
expectMsg('connected)
success
}
}
}--
>>>>>>>>>> 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.
HI Roland,
That reply really helped me out. Just one other question, I've been working a lot with TestFSMRef, and I can emulate it's behaviour using the solution you provided.
I keep going back to TestFSMRef though, and trying to figure out a way of using it to create a FSM Actor Ref, but setting the parent to testActor.
It would make my code a lot less verbose if I could figure out how to do that, but I don't think it's possible given the API.
I have been trying to set it up in the following fashion, but without any success.
var fsm: FTPFsm = _
val t = TestFSMRef({
fsm = new FTPFsm() ; fsm
})
t ! FTPDoInit(new FTPConf)
t ! 'checkfiles
expectMsg('connected)
assertion failed: timeout (3 seconds) during expectMsg while waiting for 'connected
Is this a waste of time or am I misunderstanding the Testkit API?
val t = TestFSMRef({
fsm = new FTPFsm() ; fsm
})
t ! FTPDoInit(new FTPConf)
t ! 'checkfiles
expectMsg('connected)I don’t see what you intend to do here, testActor does not appear in this code?
Yes, I couldn't figure out how to set testActor as the parent of TestFSMRef.
I guess what I was looking for was a way to do the equivalent of:
val t = TestFSMRef(new FTPFsm(), parent=testActor) //This apply method doesn't exist, but it would be nice if it did.
t ! FTPDoInit(new FTPConf)
t ! 'checkfiles
expectMsg('connected)
I don't have a huge experience with the Akka API so I just wanted to make sure I wasn't missing something basic.
Regards,
Bryan Hunt--
>>>>>>>>>> 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.
For more options, visit https://groups.google.com/groups/opt_out.