我试图将一些常见的Akka FSM代码的常见测试纳入特征,但sender
ref变为deadLetters
。使用此FSM代码:
import akka.actor.FSM
import akka.testkit.TestFSMRef
import akka.testkit.TestKit
import akka.actor.ActorSystem
import org.scalatest.Matchers
import org.scalatest.WordSpecLike
import akka.testkit.ImplicitSender
sealed trait MyState
case object StateA extends MyState
case object StateB extends MyState
case class MyData(ignored: Option[Int] = None)
class MyFSM extends FSM[MyState, MyData] {
startWith(StateA, MyData())
val common: StateFunction = {
case Event(_, _) =>
System.err.println(s"sender is $sender")
sender ! s"hello $stateName"
stay
}
when(StateA)(common)
when(StateB)(common)
}
然后我可以使用以下方法在两个规格中使用重复的测试代码测试两个状态的公共代码:
class StateASpec extends TestKit(ActorSystem()) with WordSpecLike with Matchers with ImplicitSender {
def testCommonBehaviour(testState: MyState) {
val fsm = TestFSMRef(new MyFSM())
fsm.setState(testState, MyData())
fsm ! "hello fsm"
expectMsg("hello StateA")
}
"StateA" should {
"respond to common test case" in {
testCommonBehaviour(StateA)
}
}
}
class StateBSpec extends TestKit(ActorSystem()) with WordSpecLike with Matchers with ImplicitSender {
def testCommonBehaviour(testState: MyState) {
val fsm = TestFSMRef(new MyFSM())
fsm.setState(testState, MyData())
fsm ! "hello fsm"
expectMsg("hello StateB")
}
"StateB" should {
"respond to common test case" in {
testCommonBehaviour(StateB)
}
}
}
当我尝试将常见的测试逻辑反应为一个特性:
trait TraitOfTests {
self: TestKit with ImplicitSender =>
def testCommonBehaviour(testState: MyState) {
val fsm = TestFSMRef(new MyFSM())
fsm.setState(testState, MyData())
fsm ! "hello fsm"
expectMsg("hello $testState")
}
}
class StateASpec extends TestKit(ActorSystem()) with WordSpecLike with Matchers with ImplicitSender with TraitOfTests {
"StateA" should {
"respond to common test case" in {
testCommonBehaviour(StateA)
}
}
}
class StateBSpec extends TestKit(ActorSystem()) with WordSpecLike with Matchers with ImplicitSender with TraitOfTests {
"StateB" should {
"respond to common test case" in {
testCommonBehaviour(StateB)
}
}
}
回复转到deadLetters actor:
发件人是演员[akka:// default / deadLetters] [INFO] [11/30/2014 16:15:49.812] [default-akka.actor.default-dispatcher-2] [akka:// default / deadLetters]消息[java.lang.String]来自 TestActor [akka:// default / user / $$ b]来 演员[akka:// default / deadLetters]未送达。 [1]死信 遇到。可以使用关闭或调整此日志记录 配置设置' akka.log-dead-letters'和 ' akka.log止字母-期间关断'
如何修复隐式发送方以确保当FSM actor从特征中响应测试make的调用时它会返回testActor以使expectMsg
有效?
答案 0 :(得分:0)
解决这个问题的一种方法是对你的共同特征进行轻微的重新设计,如下所示:
trait TraitOfTests {
self: TestKit =>
def testCommonBehaviour(testState: MyState)(implicit sender:ActorRef) {
val fsm = TestFSMRef(new MyFSM())
fsm.setState(testState, MyData())
fsm ! "hello fsm"
expectMsg("hello $testState")
}
}
如果您在testCommonBehavior
上定义了隐式发件人,那么您可以放心,它会从您通过ImplicitSender