有没有办法在 Actor 的接收定义中获取 "stored" 值?
Is there a way to obtain the "stored" value within a receive definition of an Actor?
我希望能够针对“存储”到我的参与者的接收函数中的值进行断言。有没有办法用任何 Akka 测试库来做到这一点?
在下面的例子中,我想获得currentCount
。
import akka.actor.Actor
class CounterActor extends Actor {
import CounterActor._
override def receive: Receive = count(0)
def count(currentCount: Int): Receive = {
case Increment => context.become(count(currentCount + 1))
case Decrement => context.become(count(currentCount - 1))
}
}
object CounterActor {
case object Increment
case object Decrement
}
然后我想用测试来反对它 class:
val counterActorRef = TestActorRef(new CounterActor())
"A counter actor" should {
"have a count of 3" in {
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
val counterValue = // obtain currentCount from counterActorRef
assert(counterValue == 3)
}
}
我试过使用 TestActorRef,但没有成功。我知道有一种方法可以通过添加消息案例来获得它来满足这一点,或者添加一些 Debug/Info 级别的日志消息并使用 EventFilter
。有没有简单的方法可以通过我不知道的测试库来获取它?
我已经在 akka.testkit
个库中搜索了一段时间,但找不到我的解决方案。
感谢任何帮助,谢谢。
您想做什么 - ask
演员关于他的状态和 assert
它在测试中的状态。
第一步——读取值:
import akka.actor.Actor
class CounterActor extends Actor {
import CounterActor._
override def receive: Receive = count(0)
def count(currentCount: Int): Receive = {
case Increment => context.become(count(currentCount + 1))
case Decrement => context.become(count(currentCount - 1))
case Read => sender() !
}
}
object CounterActor {
case object Increment
case object Decrement
case object Read
case class CurrentValue(currentCount: Int) //for type safety
}
第二步 - 在测试中断言:
val counterActorRef = TestActorRef(new CounterActor())
"A counter actor" should {
"have a count of 3" in {
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
val counterValue = (counterActorRef ? Read).futureValue
assert(counterValue == CurrentValue(3))
}
}
演员模型有两个特点:
actor 状态的封装是彻底的并且(在 JVM 上,有效地(因为可能通过反射破坏封装))完成。
观察到 actor 的状态仅在其行为(它如何响应消息,以及在 Akka 的情况下(它不是“actors all the way down”)的情况下才重要)是什么它执行的副作用)会因该状态而改变。
为了验证状态转换是否发生,您只能测试其行为是否符合预期。公开查询消息是一种方法;诸如点击日志条目流或(如果是事件源,则为持久性事件流)之类的东西是其他的。
也就是说,仅出于启用可测试性的目的公开查询消息通常不是可行的方法(它可能对操作调试有用)。理想的情况是测试参与者响应状态变化的“带内”行为(例如,“在发送 A 为真的消息后,对 B 为真的消息的响应显示 属性 C”)。如果状态改变没有以某种方式表现为行为改变,为什么状态改变会发生?
换句话说,将其他参与者视为黑盒服务通常很好。如果你正在测试 SO,你不可能验证“在 posting 一个问题之后,数据库中的这个字段被设置为这个值”(因为你作为用户无权访问数据库并且你不能提供一个你控制的模拟)。您可以验证的是“当我 post 一个问题时,我会得到一个问题 ID,当我请求该 ID 时,我会得到问题的内容”。
我希望能够针对“存储”到我的参与者的接收函数中的值进行断言。有没有办法用任何 Akka 测试库来做到这一点?
在下面的例子中,我想获得currentCount
。
import akka.actor.Actor
class CounterActor extends Actor {
import CounterActor._
override def receive: Receive = count(0)
def count(currentCount: Int): Receive = {
case Increment => context.become(count(currentCount + 1))
case Decrement => context.become(count(currentCount - 1))
}
}
object CounterActor {
case object Increment
case object Decrement
}
然后我想用测试来反对它 class:
val counterActorRef = TestActorRef(new CounterActor())
"A counter actor" should {
"have a count of 3" in {
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
val counterValue = // obtain currentCount from counterActorRef
assert(counterValue == 3)
}
}
我试过使用 TestActorRef,但没有成功。我知道有一种方法可以通过添加消息案例来获得它来满足这一点,或者添加一些 Debug/Info 级别的日志消息并使用 EventFilter
。有没有简单的方法可以通过我不知道的测试库来获取它?
我已经在 akka.testkit
个库中搜索了一段时间,但找不到我的解决方案。
感谢任何帮助,谢谢。
您想做什么 - ask
演员关于他的状态和 assert
它在测试中的状态。
第一步——读取值:
import akka.actor.Actor
class CounterActor extends Actor {
import CounterActor._
override def receive: Receive = count(0)
def count(currentCount: Int): Receive = {
case Increment => context.become(count(currentCount + 1))
case Decrement => context.become(count(currentCount - 1))
case Read => sender() !
}
}
object CounterActor {
case object Increment
case object Decrement
case object Read
case class CurrentValue(currentCount: Int) //for type safety
}
第二步 - 在测试中断言:
val counterActorRef = TestActorRef(new CounterActor())
"A counter actor" should {
"have a count of 3" in {
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
counterActorRef ! CounterActor.Increment
val counterValue = (counterActorRef ? Read).futureValue
assert(counterValue == CurrentValue(3))
}
}
演员模型有两个特点:
actor 状态的封装是彻底的并且(在 JVM 上,有效地(因为可能通过反射破坏封装))完成。
观察到 actor 的状态仅在其行为(它如何响应消息,以及在 Akka 的情况下(它不是“actors all the way down”)的情况下才重要)是什么它执行的副作用)会因该状态而改变。
为了验证状态转换是否发生,您只能测试其行为是否符合预期。公开查询消息是一种方法;诸如点击日志条目流或(如果是事件源,则为持久性事件流)之类的东西是其他的。
也就是说,仅出于启用可测试性的目的公开查询消息通常不是可行的方法(它可能对操作调试有用)。理想的情况是测试参与者响应状态变化的“带内”行为(例如,“在发送 A 为真的消息后,对 B 为真的消息的响应显示 属性 C”)。如果状态改变没有以某种方式表现为行为改变,为什么状态改变会发生?
换句话说,将其他参与者视为黑盒服务通常很好。如果你正在测试 SO,你不可能验证“在 posting 一个问题之后,数据库中的这个字段被设置为这个值”(因为你作为用户无权访问数据库并且你不能提供一个你控制的模拟)。您可以验证的是“当我 post 一个问题时,我会得到一个问题 ID,当我请求该 ID 时,我会得到问题的内容”。