【发布时间】:2015-09-04 04:08:41
【问题描述】:
我有一个演员 Dispenser。它的作用就是它
- 按要求分配一些对象
- 聆听新的到来
代码如下
class Dispenser extends Actor {
override def receive: Receive = {
case Get =>
context.sender ! getObj()
case x: SomeType =>
addObj(x)
}
}
在实际处理中,从发送新对象到分发器开始分发它是否经过 1 毫秒甚至几秒钟都没有关系,因此没有代码跟踪它。
但现在我正在为分配器编写测试,我想确保它首先收到新对象,然后才收到 Get 请求。
这是我想出的测试代码:
val dispenser = system.actorOf(Props.create(classOf[Dispenser]))
dispenser ! obj
Thread.sleep(100)
val task = dispenser ? Get()
val result = Await.result(task, timeout)
check(result)
它满足一项重要要求 - 它不会更改原始代码。但它是
- 即使在非常高性能的机器上也至少慢 100 毫秒
- 不稳定且有时会失败,因为 100 ms 或任何其他常量不提供任何保证。
问题是如何进行满足要求且没有上述缺点的测试(没有任何其他明显的缺点)
【问题讨论】:
-
您可能必须将测试参数化:将睡眠时间更改为 1 毫秒,然后运行很多次。如果它在 > 92% 的时间内工作,则测试通过。 92% 是我凭空得出的一个数字。选择您的号码并满意。
-
我不认为在 8%(甚至 0.01%)的情况下终止部署过程(包括运行自动化测试)是进行测试的正确方法。所以我更喜欢不涉及统计的解决方案
-
在 akka 的第一个版本中,有一个基于邮箱大小的解决方案。对于 akka2,此功能已禁用。但是邮箱仍然可以自己实现。但是否存在更简单、更直观的解决方案?
-
@Daenyth 感谢您的链接。我对类似于询问模式的解决方案持开放态度,在成功交付的情况下一切正常,在其他情况下,它等待的时间不超过给定的超时时间。
标签: multithreading scala akka actor