簡體   English   中英

異步代碼的單元測試

[英]Unit test for asynchronous code

我有一些代碼,它使用HttpWebRequest類的.BeginGetResponse()方法,它是異步的。 此外,我正在使用Microsoft的Unit Test App項目來測試應用程序。

問題是測試框架沒有等待運行異步代碼的結束,所以我無法檢查其結果。

我應該如何使用Unit Test App項目測試異步代碼? 我沒有使用async / await modificators。

更新答案
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)); 

檢查接受的答案 ,該答案使用Silverlight單元測試框架對異步代碼進行單元測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM