如何最佳地对异步方法进行单元测试?

15

我似乎找不到一个针对这个问题的.NET答案,但我认为这应该是相当常见的。
单元测试异步方法的最佳模式是什么?

显然,我需要调用方法,然后看回调是否触发,但除了简单地睡一会儿然后检查回调设置的标志外,还有更好的方法吗?在多个测试运行时管理标志会变得有些混乱。

3个回答

10

我通常使用匿名委托和等待句柄。例如,我的Presenter中有一个名为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);
}

2
将代码拆分,使逻辑位于同步代码中,并由薄异步包装器调用。
然后,大多数单元测试可以测试同步代码。

1
有没有比简单睡眠一会儿,然后检查回调设置的标志更好的方法?
用等待句柄替换标志。不要设置标志,而是设置等待句柄。不要睡眠,然后检查标志是否设置,而是等待等待句柄……并在超时时等待,这样如果您因为计时器过期而醒来,而不是因为您等待的句柄被回调触发而醒来,则说明测试失败(即回调未在超时时间内调用)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接