我一直在项目中使用Rx,更具体地说是ReactiveUI,并且我已经陷入了一种我认为需要一些建议的情况。
问题是,如果执行一个命令(单击一个按钮),我想显示一个消息框,用户将回答是或否。根据答案,我想要做更多的东西。当我使用MVVM进行单元测试时,我希望MessageBox可以测试;即被其他一些代码所取代。这基本上就是我所拥有的。
在我的视图模型中:
this.ExternalObservable = this.SomeOperationCommand
.SelectMany(_ => this.UserWantsToContinueWithOperation())
.Where(x => x)
.Select(_ => this.SomeData)
.Where(x => x != null);
private IObservable<bool> UserWantsToContinueWithOperation() {
var subject = new Subject<bool>();
var box = new GuiMsgBox("Continue?",
result => {
subject.OnNext(result == System.Windows.MessageBoxResult.Yes);
});
MessageBus.Current.SendMessage(box);
return subject;
}
GuiMsgBox
本质上是System.Windows.MessageBox
类的包装器,我在UI和测试中使用MessageBus
来听。
这在运行应用程序时工作正常,但在单元测试中,由于总线正在使用立即调度程序,显然它的工作方式不同。
我觉得这里有一些设计故障,所以对实际问题有任何意见;显示一个消息框,返回一个可以测试的结果,将不胜感激!
答案 0 :(得分:1)
如果没有看到更多的实现细节,很难说,但我会考虑使用TestScheduler。在RxUI.Testing中,这很简单:
(new TestScheduler()).With(sched => {
// Write your test here, all the schedulers will be
// implicitly set to your 'sched' scheduler.
});
以下是一系列与MVVM相关的测试示例,测试番茄钟计时器:
这是基于MVVM的测试的另一个很好的例子from my Rx book(抱歉插件),特别是使用CreateColdObservable来模拟输入(即测试“点击按钮,等待10秒,检查结果”的场景) )