简体   繁体   English

异步代码的单元测试

[英]Unit test for asynchronous code

I have got some code, which is using HttpWebRequest class's .BeginGetResponse() method and it is asynchronous. 我有一些代码,它使用HttpWebRequest类的.BeginGetResponse()方法,它是异步的。 Also, I am using Microsoft's Unit Test App project for testing application. 此外,我正在使用Microsoft的Unit Test App项目来测试应用程序。

The problem is that test framework does not waiting for end of running asynchronous code, so I can not check its result. 问题是测试框架没有等待运行异步代码的结束,所以我无法检查其结果。

How should I test asynchronous code using Unit Test App project? 我应该如何使用Unit Test App项目测试异步代码? I'm not using async/await modificators. 我没有使用async / await modificators。

Update Answer 更新答案
The original answer was quite an old one, before async and await were prevalent. asyncawait盛行之前,最初的答案是相当古老的。 I'd now recommend using them, by writing something like: 我现在推荐使用它们,通过写下这样的东西:

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

There's a good article that covers this in depth Async Programming : Unit Testing Asynchronous Code 有一篇很好的文章深入介绍了异步编程:单元测试异步代码

Old Answer 老答案

I would tend to something simple like using a polling loop and checking a flag that would be set in the async code or you could use reset events. 我倾向于简单的事情,比如使用轮询循环并检查将在异步代码中设置的标志,或者您可以使用重置事件。 A simple example using threads: 一个使用线程的简单示例:

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

    done.WaitOne();
}

You'll need to think about exceptions and use a try/finally and report the errors to do this properly, but you get the idea. 您需要考虑异常并使用try / finally并报告错误以正确执行此操作,但您明白了。 This method however might not suit if you're doing lots of async stuff over and over, unless you fancy pushing this into a reusable method. 但是,如果你反复做很多异步的东西,这个方法可能不适合,除非你想把它推到一个可重用的方法中。

You could also use async/await pattern (using the HttpWebRequest wrapper from the Microsoft.Bcl.Async nuget package ). 您还可以使用async / await模式(使用Microsoft.Bcl.Async nuget包中HttpWebRequest包装器)。 This will also neatly handle any exceptions that occur in your background thread. 这也将整齐地处理后台线程中发生的任何异常。

For example: 例如:

[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)); 

检查接受的答案 ,该答案使用Silverlight单元测试框架对异步代码进行单元测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM