我有一个要为其编写测试的简单发布订阅者。
这里调用的方法都是行为,除了get_number_consumed_messages
是函数。
class iso _SinglePubSub is UnitTest
fun name(): String => "single publish/consume"
fun apply(h: TestHelper) =>
let p = Publisher("publisher message", h.env.out)
let queue = Queue(1, h.env.out)
let c = Consumer(h.env.out)
p.publish_message(queue)
p.publish_message(queue)
c.consume_message(queue)
c.consume_message(queue)
//Run after all behaviours are done
let n = c.get_number_consumed_messages()
h.assert_eq[USize](2, n)
某人将如何实现get_number_consumed_messages
函数/行为或您将如何修改测试函数?
答案 0 :(得分:0)
首先,c.get_number_consumed_messages()
也必须是一种行为。这是让一个演员与另一个演员交流的唯一方法。这样做还有一个好处,那就是,行为按照与调用它们相同的顺序运行,这意味着c.get_number_consumed_messages()
将在两次调用c.consume_message(queue)
之后运行。
鉴于Consumer
也是一个参与者,因此用行为(而不是方法)来调用它意味着我们不能直接从中返回数据。要实际从其他演员接收数据,您应该使用Promise pattern,例如:
use "promises"
actor Consumer
var message_count: USize = 0
be consume_message(queue: OutStream) =>
... // Do some things
message_count = message_count + 1
... // Do other things
be get_number_consumed_messages(p: Promise[USize]) =>
p(message_count)
要进行实际测试,您需要遵循{em> Testing Notifier Interactions pattern的改版进行长时间测试,例如:
use "ponytest"
use "promises"
class iso _SinglePubSub is UnitTest
fun apply(h: TestHelper) =>
h.long_test(2_000_000_000)
... // Produce and consume messages
let p = Promise[USize]
p.next[None]({(n: USize): None =>
h.assert_eq[USize](2, n)
h.complete(true) })
c.get_number_consumed_messages(p)
(请注意对h.long_test
和h.complete
的额外调用,以及在测试结束时用lambda包装的承诺。)
有关这些概念的更多信息,建议您熟悉Promises和"Long tests" section of Ponytest上的stdlib文档。