在小马所有行为结束后运行功能/行为

时间:2019-06-15 16:52:28

标签: unit-testing testing publish-subscribe ponylang

我有一个要为其编写测试的简单发布订阅者。 这里调用的方法都是行为,除了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函数/行为或您将如何修改测试函数?

1 个答案:

答案 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_testh.complete的额外调用,以及在测试结束时用lambda包装的承诺。)

有关这些概念的更多信息,建议您熟悉Promises"Long tests" section of Ponytest上的stdlib文档。