2015-04-14 157 views
0

我有以下的事件處理程序 - 它使用Dispatcher.BeginInvoke我相信這是對的BeginInvoke類似的另一個堆棧溢出問題不同:異步方法測試

private void source_load_complete() 
    { 
     Dispatcher.BeginInvoke(new NotificationDelegate(source_load_complete_ui), null); 
    } 

然後:

private void source_load_complete_ui() 
    { 
     m_image.Image = m_bmp.CreateBitmap(); 
     m_image.UpdateImage(null); 
     m_image.LoadComplete = true; 
     raise_property_changed("CurrentImage"); 
    } 

並測試這個,下面的測試方法:

[TestMethod] 
    public void ImageVM_SourceLoadTests() 
    { 
     ImageViewModel ivm = new ImageViewModel(); 
     List<string> eventList = new List<string>(); 

     ivm.PropertyChanged += delegate(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
     { 
      eventList.Add(e.PropertyName); 
     }; 

     // check the model is set up correctly so the event in the constructor works 
     CustomImage model = ivm.ImageModel as CustomImage; 
     WriteableBitmap bmp = model.Image; 

     if(model.ImageSource.LoadComplete != null) 
     { 
// fire off the event we want to test is handled correctly 
      model.ImageSource.LoadComplete(); 
     } 

     Assert.IsTrue(model.LoadComplete == true); 
     Assert.IsTrue(model.Image == bmp); 
     Assert.IsTrue(eventList.Count == 1); 
    } 

顯然這不會窩窩rk,因爲source_load_complete_ui方法是異步調用的。然而,我無法找出如何最好的測試,並等待異步方法被調用?

編輯: 我沒有提到,這個類繼承Dispatcher對象,因此BeginInvoke的是不相關的給出了答案:

public class ImageViewModel : DispatcherObject, INotifyPropertyChanged 

因此不是重複建議

+1

可能重複[如何進行單元測試的BeginInvoke上的動作](http://stackoverflow.com/questions/5885993/how-to-unit-test-begininvoke-on-an-action) – Orace

+0

我我們將仔細研究它,但它正在討論我相信的另一種BeginInvoke方法 – Zief

回答

0

在end我認爲這個答案實際上與這個答案相關Using the WPF Dispatcher in unit tests

使用本答案中描述的調度器幫助程序util,可以強制它處理隊列並在單元測試中使用它。的

public static class DispatcherUtil 
{ 

[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] 
public static void DoEvents() 
{ 
    DispatcherFrame frame = new DispatcherFrame(); 
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
     new DispatcherOperationCallback(ExitFrame), frame); 
    Dispatcher.PushFrame(frame); 
} 

private static object ExitFrame(object frame) 
{ 
    ((DispatcherFrame)frame).Continue = false; 
    return null; 
} 
}