单元测试异步方法的最佳方法是什么?

问题描述:

我似乎无法找到这个问题的.NET答案,我认为这将是相当普遍的。
单元测试异步方法的最佳模式是什么?单元测试异步方法的最佳方法是什么?

很明显,我需要调用该方法,然后看看回调是否触发,但是有没有比简单地睡一会然后检查回调设置的标志更好的方法?在有多个测试运行的地方,管理标志会有点混乱。

我通常使用匿名委托和等待句柄。例如我在我的演示器中有一个名为SetRemoteTableName的函数。名称设置后,它也会引发一个事件。我想测试那个异步引发的事件。测试如下所示:

[TestMethod] 
[WorkItem(244)] 
[Description("Ensures calling SetRemoteTableName with a valid name works 
       AND raises the RemoteTableNameChange event")] 
public void SetRemoteTableNamePositive() 
{ 
    string expected = "TestRemoteTableName"; 
    string actual = string.Empty; 

    AutoResetEvent are = new AutoResetEvent(false); 
    SQLCECollectorPresenter presenter = new SQLCECollectorPresenter(); 
    presenter.RemoteTableNameChange += new EventHandler<GenericEventArg<string>>(
    delegate(object o, GenericEventArg<string> a) 
    { 
     actual = a.Value; 
     are.Set(); 
    }); 

    presenter.SetRemoteTableName(expected); 
    Assert.IsTrue(are.WaitOne(1000, false), "Event never fired"); 
    Assert.AreEqual(actual, expected); 
} 
+0

这真是太棒了 - 谢谢! – womp 2009-05-13 20:36:05

拆分代码,以便逻辑位于由瘦异步封装器调用的代码的同步位中。

然后,大多数单元测试可以测试同步代码。

有没有比简单的休息一下再检查一个由回调设置的标志更好的方法?

用等待句柄替换该标志。而不是设置标志,设置等待句柄。而不是睡觉,然后检查是否设置标志,等待等待处理...并等待超时,以便如果您由于定时器到期而醒来,而不是因为您等待的句柄被解除而醒来通过回调,那么你知道测试失败了(即在超时期内没有调用回调)。