2010-04-23 111 views
1

我有一個ViewModel,它在構造函數中開始加載模型異步,並在加載模型時觸發一個事件。我有一個測試用的Silverlight單元測試框架的工作,像這樣:如何等待Silverlight測試中觸發事件

bool done = false; 

[TestMethod] 
[Asynchronous] 
public void Test_NoCustomerSelected() 
{ 
    ProjectListViewModel viewModel = null; 
    EnqueueCallback(() => viewModel = new ProjectListViewModel()); 
    EnqueueCallback(() => viewModel.ModelLoaded += new EventHandler<EventArgs>(viewModel_ModelLoaded)); 

    EnqueueConditional(() => done); 
    EnqueueCallback(() => Assert.IsNotNull(viewModel.FilteredProjectList)); 
    EnqueueCallback(() => Assert.AreEqual(4, viewModel.FilteredProjectList.Count)); 

    EnqueueTestComplete(); 
} 

void viewModel_ModelLoaded(object sender, EventArgs e) 
{ 
    done = true; 
} 

但我已經開始,其中Rx框架玩,並試圖讓我的測試工作,但到目前爲止,我沒有運氣。這裏有2次嘗試:

public void Test_NoCustomerSelected2() 
{ 
    ProjectListViewModel viewModel = null; 
    viewModel = new ProjectListViewModel(eventAggregatorMock.Object, moduleManagerMock.Object); 

    IObservable<IEvent<EventArgs>> eventAsObservable = Observable.FromEvent<EventArgs>(
     ev => viewModel.ModelLoaded += ev, 
     ev => viewModel.ModelLoaded -= ev); 

    eventAsObservable.Subscribe(args => viewModel_ModelLoaded(args.Sender, args.EventArgs)); 
    eventAsObservable.First(); 

    Assert.IsNotNull(viewModel.Model); 
    Assert.AreEqual(4, viewModel.Model.Count); 
} 

[TestMethod] 
public void Test_NoCustomerSelected3() 
{ 
    ProjectListViewModel viewModel = null; 

    var o = Observable.Start(() => viewModel = new ProjectListViewModel(eventAggregatorMock.Object, moduleManagerMock.Object)); 

    IObservable<IEvent<EventArgs>> eventAsObservable = Observable.FromEvent<EventArgs>(
     ev => viewModel.ModelLoaded += ev, 
     ev => viewModel.ModelLoaded -= ev); 

    o.TakeUntil(eventAsObservable) 
      .First(); 

    Assert.IsNotNull(viewModel.Model); 
    Assert.AreEqual(4, viewModel.Model.Count); 
} 

第一次測試中那張永遠等待,第二不起作用,因爲視圖模型爲空時,它的FromEvent。

任何人都有一個線索如何正確地做到這一點?

更新:下面是從PL幫助工作的解決方案:

[TestMethod] 
public void Test_NoCustomerSelected4() 
{ 
    var viewModel = new ProjectListViewModel(eventAggregatorMock.Object, moduleManagerMock.Object); 

    Observable 
     .FromEvent<EventArgs>(viewModel, "ModelLoaded")) 
     .Take(1) 
     .Subscribe(e => 
      { 
       Assert.IsNotNull(viewModel.Model); 
       Assert.AreEqual(4, viewModel.Model.Count); 
      }); 
} 

回答

2

我相信你還是要用排隊調用。例如。這樣的事情:

var done = false; 
var viewModel = new ProjectListViewModel(eventAggregatorMock.Object, moduleManagerMock.Object); 

Observable 
    .FromEvent<EventArgs>(viewModel, "ModelLoaded")) 
    .Take(1) 
    .Subscribe(viewModel => 
     { 
      Assert.IsNotNull(viewModel.Model); 
      Assert.AreEqual(4, viewModel.Model.Count); 
      done = true; 
     }); 

EnqueueConditional(() => done); 
EnqueueTestComplete(); 
+0

這工作,只有問題,我不得不改變。訂閱(E => ...),並完成en Enqueue是不需要的。謝謝PL。 – 2010-04-23 20:05:16