我有一个ViewModel,它开始在构造函数中加载Model async,并在加载Model时触发一个事件。我使用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 Framework,试图让我的测试工作,但到目前为止我没有运气。这是两次尝试:
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时,viewModel为null。
任何人都知道如何正确地做到这一点?
更新:在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);
});
}
答案 0 :(得分:2)
我相信你仍然需要使用Enqueue电话。例如。像这样的东西:
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();