异步代码的单元测试

时间:2013-06-19 08:12:40

标签: c# unit-testing windows-phone-8

我有一些代码,它使用的是HttpWebRequest类的.BeginGetResponse()方法,它是异步的。此外,我正在使用Microsoft的Unit Test App项目来测试应用程序。

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

我应该如何使用Unit Test App项目测试异步代码?我没有使用async / await modificators。

4 个答案:

答案 0 :(得分:5)

更新答案
asyncawait普遍存在之前,原始答案相当古老。我现在推荐使用它们,写下类似的东西:

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

有一篇很好的文章深入探讨了这一点Async Programming : Unit Testing Asynchronous Code

旧答案

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

[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并报告错误以正确执行此操作,但您明白了。但是,如果你反复做很多异步的东西,这个方法可能不适合,除非你想把它推到一个可重用的方法中。

答案 1 :(得分:2)

您还可以使用async / await模式(使用Microsoft.Bcl.Async nuget package中的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);
}

答案 2 :(得分:0)

现在已经晚了,但我想这会更具可读性和真实性

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

答案 3 :(得分:-1)

检查已接受的answer,它使用Silverlight单元测试框架对异步代码进行单元测试。

相关问题