测试被动异步代码的策略

Arn*_*rne 7 .net c# unit-testing asynchronous

我正在开发面向数据流的特定于域的语言.为了简化,让我们看一下操作.操作具有许多命名参数,可以要求它们使用当前状态计算结果.

要确定操作何时应该生成结果,它会获得一个对哪个参数从谁获取值敏感的决策.当此决定确定已满足时,它将使用观察者发出信号.

Accessor侦听此Signal,然后调用Operation的Result方法,以便将其复用到其他Operations的参数.

到目前为止,这么好,很好地解耦设计,可组合和可重用,并且根据所使用的特定Observer,可以像你想要的那样异步.

现在,这里是我的问题:我会开始编码针对这种设计实际测试.但是使用异步Observer ......

  • 我怎么知道整个信号和参数管道工作?
  • 我是否需要在等待信号时使用超时才能说它是否成功发射?
  • 如果我等待一段时间(停止问题?;-)),我怎么能正式确定信号不会发出?
  • 并且,我如何确定信号是否被发射,因为我是谁设置参数,而不是另一个操作?很可能是我的测试提前到来并且看到在我设置参数之前发出的信号导致决策发出它.

目前,我猜这些琐碎的案例很容易测试,但是一旦我想测试复杂的多对多 - 操作之间的情况,我必须求助于设计Just Works(tm)......

编辑(1):

让我们考虑以下场景:

想象一下操作A为操作B1,B2和B3提供值的情况,每个操作都有一个On-Every-Input-Decision(每当更新任何参数时都会满足).然后,让B1和B2以及B3各自将它们的值提供给操作C的相同参数(为了比较,例如,将这些值聚合到查找表或某些等中).

预期的步骤是:

  1. 表示它具有新值(根据其决定)
  2. 一段时间后,异步Observer将Signal发送到已注册的任何内容
  3. 啊,一个Accessor注册.调用它的回调,然后获取操作的结果并将其多路复用到B1,B2和B3的参数
  4. B1,B2和B3通知他们的决定,为观察者创建三个新的信号
  5. 一段时间后,异步Observer调度B1的信号,然后是B2,然后是B3
  6. 每个信号都会导致Accessor获取B1的结果(2,3)并将其输入C

所以,我知道在这种情况下,我可以模拟例如C的决定,看看它是否确实了解了B1,B2和B3的作用.问题是:我什么时候可以检查这个?

编辑(2):我的目标似乎更像是端到端测试,即将DSL的各个部分组合在一起,看看结果是否符合我的预期.

编辑(3):结果我过于复杂了:-)

And*_*son 2

您需要确保所有不同的组件都已连接出来,然后一次测试一个特定的类,模拟出其他所有组件。

注意:此解释假定您正在使用依赖倒置的原则以及模拟库(如Rhino Mocks)。

你说:

为了决定操作何时应产生结果,它会获得一个决策,该决策对哪个参数从谁那里获取值很敏感。当该决策确定其已实现时,它会使用观察者发出信号。

访问器侦听此信号,然后调用操作的 Result 方法,以便将其复用到其他操作的参数。

这对我来说意味着您将构建一个具有模拟 IDecision 的操作。然后,您的单元测试可以编排 IDecision 的行为,以演练操作可能必须处理的所有可能场景。

同样,您的 Accessor 测试有一个模拟 IDecision,它被设置为以真实的方式运行,以便您可以完全独立地测试 Accessor 类。它还可以有一个模拟 IOperation,您可以测试您的访问器是否调用模拟对象上的适当方法来响应所需的刺激。

摘要: 单独测试每个类,使用所有其他部分的模拟对象来编排适当的行为。