异步代码的单元测试

本文关键字:单元测试 代码 异步 | 更新日期: 2023-09-27 18:18:56

我得到了一些代码,这是使用HttpWebRequest类的.BeginGetResponse()方法,它是异步的。此外,我正在使用微软的单元测试应用程序项目来测试应用程序。

问题是测试框架没有等待运行异步代码的结束,所以我不能检查它的结果。

我应该如何使用单元测试应用程序项目测试异步代码?我没有使用async/await修饰符

异步代码的单元测试

更新答案
原来的答案是相当古老的,在asyncawait流行之前。我现在推荐使用它们,像这样写:

[TestMethod]
public async Task RunTest()
{
    var result = await doAsyncStuff();
    // Expectations
}

有一篇很好的文章深入介绍了异步编程:单元测试异步代码

老回答

我倾向于一些简单的东西,比如使用轮询循环和检查将在异步代码中设置的标志,或者您可以使用重置事件。一个使用线程的简单示例:

[TestMethod]
public void RunTest()
{
    ManualResetEvent done = new ManualResetEvent(false);
    Thread thread = new Thread(delegate() {
        // Do some stuff
        done.Set();
    });
    thread.Start();
    done.WaitOne();
}

你需要考虑异常,并使用try/finally和报告错误来正确地做到这一点,但是你明白了。然而,如果你反复做很多异步的事情,这个方法可能不适合,除非你想把它推到一个可重用的方法中。

您也可以使用async/await模式(使用Microsoft.Bcl.Async nuget包中的HttpWebRequest包装器)。这也将巧妙地处理发生在后台线程中的任何异常。

例如:

[TestMethod]
public void RunTest()
{
    bool asyncDone = false;
    // this is a dummy async task - replace it with any awaitable Task<T>
    var task = Task.Factory.StartNew(() => 
    {
        // throw here to simulate bad code
        // throw new Exception();
        // Do some stuff
        asyncDone = true;
    });
    // Use Task.Wait to pause the test thread while the background code runs.
    // Any exceptions in the task will be rethrown from here.
    task.Wait();
    // check our result was as expected
    Assert.AreEqual(true, asyncDone);
}

有点晚了,但我想这样会更容易读,更真实

await Task.Delay(TimeSpan.FromSeconds(5));