测试被动异步代码的策略

时间:2010-06-17 19:25:20

标签: c# .net unit-testing asynchronous

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

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

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

到目前为止,一切都很好,很好的分离设计,可组合,可重复使用,并根据所使用的具体观察,异步,你希望它是。

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

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

目前,我想简单的情形很容易测试,但只要我想测试复杂许多一对多 - 操作之间的情况下,我必须求助于希望设计工作的很好(TM)... < / p>

编辑(1):

让我们考虑以下情况:

想象这样的操作的提供值的操作B1,B2和B3,每一个都具有在-每路输入判定(一个每当任何参数被更新时被满足时)的情况。然后,让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
  7. 所以,我知道在这种情况下我可以模仿,例如C的决定,看看它是否确实了解了B1,B2和B3的作用。问题是:什么时候我可以安全检查一下吗?

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

    编辑(3):事实证明我过于复杂: - )

2 个答案:

答案 0 :(得分:2)

您需要确保所有不同的组件都已接口,然后一次测试一个特定的类,嘲笑其他所有组件。

注意:此解释预先假定您使用依赖性反转原理以及模拟库(如Rhino Mocks)。

你说:

  

决定何时应该进行操作   产生一个结果,它得到一个决定   这对哪个参数很敏感   得到了谁的价值。当这个   决定决定它已实现,   它使用观察者发出信号。

     

Accessor侦听此信号   然后调用Result方法   操作以便复用它   到其他操作的参数。

这告诉我你将构建一个具有模拟IDecision的操作。然后,您的单元测试可以编排IDecision的行为,以便执行操作可能必须处理的所有可能方案。

同样,您的Accessor测试具有模拟IDecision,其设置为以逼真的方式运行,以便您可以单独完全测试Accessor类。它也可以有一个模拟IOperation,你可以测试你的Accessor在模拟对象上调用适当的方法来响应所需的刺激。

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

答案 1 :(得分:1)

我没有使用过这个,但我听说Reactive Framework可以用于将事件转换为Linq语句 - 然后可以用它来实现简单的单元测试。

我相信他们如何对大量Silverlight代码进行单元测试 - 事实上,Reactive框架随Silverlight Toolkit(System.Reactive.dll)一起发布。