2009-09-11 25 views
4

我想單元測試,使用VS單元測試設施以下方法。如何單元測試BackgroundWorker C#

void Get(string name, Action<string> callBack); 

這裏是單元測試

[TestMethod] 
    public void Test() 
    { 
     Action<string> cb = name => 
     { 
      Assert.IsNotNull(name); 
     }; 

     var d = new MyClass(); 
     d.Get("test", cb); 
    } 

唯一的問題是內部實現使用BackgroundWorker,因此將回調調用另一個線程。這是內部實現。

public void Get(string name, Action<string> callBack) 
    { 
     callBackString = callBack; 
     GetData(name); 
    } 

    private void GetData(string name) 
    { 
     BackgroundWorker bw = new BackgroundWorker(); 
     bw.DoWork += bw_DoWork; 
     bw.RunWorkerCompleted += bw_RunWorkerCompleted; 
     bw.RunWorkerAsync(name); 
    } 

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     //do work here 
     if (null != callBackString) 
      callBackString("ok"); 
    } 

當然,因爲Get()立即返回,所以測試完成並且測試停止,因此RunWorkerCompleted永遠不會被執行。我可以很容易地通過普通應用程序(WPF)測試它,因爲它仍然在運行,但我想有能力對此進行單元測試。

任何想法? 在此先感謝。

回答

7

喜歡的東西:

[TestMethod] 
public void Test() 
{ 
    bool running = true; 
    string result = null; 

    Action<string> cb = name => 
    { 
     result = name; 
     running = false; 
    }; 

    var d = new MyClass(); 
    d.Get("test", cb); 

    while(running) 
    { 
     Thread.Sleep(100); 
    } 

    Assert.IsNotNull(result); 
} 

雖然你可能要添加在了什麼事,如果它不能從運行下去停止測試...

4

我不知道C#&細節BackgroundWorker,但我會通過注入BackgroundWorker實現來完成此任務,並且在測試過程中使用一個可以控制其執行時間以及在哪個線程中的存根BackgroundWorker。如果需要兩個線程之間的通信,則讓BackgroundWorker創建一個新線程並讓測試暫停直到完成,如果不是在調用get之後強制它運行。

+0

當BackgroundWorker沒有實現任何接口時,你怎麼能做到這一點? – Nick 2013-10-02 19:47:17

+0

您可以製作自己的包裝BackgroundWorker的類並實現一個接口,然後僞造 – reggaeguitar 2016-05-10 22:24:09

0

我寫了類似的代碼,並按照IAsyncResult design pattern進行測試。我的單元測試是針對方法的同步(阻塞)版本運行的。異步方法可以是每行一行,所以我沒有針對這些方法編寫單元測試。

+1

,我可以用同步(阻塞)方式實現另一個版本的Get(),然後讓客戶端處理IAsyncResult設計模式,但這正是我首先想避免的。客戶不需要知道實施細節。它只是提供一個回調,稍後會調用。 – Sherlock 2009-09-11 20:49:41