ReactiveUI MessageBus 和 MessageBox 以及结果
我在一个项目中使用 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
类的包装器,我使用MessageBus
在UI 和我的测试。
在运行应用程序时,这一切都工作正常,但在单元测试中,由于总线随后使用立即调度程序,因此它显然不会以相同的方式工作。
我觉得这里存在一些设计故障,因此请对实际问题提出任何意见;显示一个消息框,返回一个可以测试的结果,将不胜感激!
I've been using Rx and more specifically ReactiveUI for a while in a project and have got myself into a situation where I think I need some advice.
The problem is that, given a command is executed (a button is clicked) I want to show a message box, one which the user will answer Yes or No. Depending on the answer, I then want to do some more stuff. As I'm using MVVM with unit tests I'd like the MessageBox to be testable; i.e. to be replaced by some other code. This is essentially what I've got.
In my view model:
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;
}
And the GuiMsgBox
is essentially a wrapper around the System.Windows.MessageBox
class which I listen to using the MessageBus
in the UI and in my tests.
This all works fine when running the application, but in unit tests, as the bus is then using the Immediate scheduler, it's obviously not working the same way.
I feel there's some design glitch here, so any input on the actual problem; to show a message box, returning a result, which can be tested, would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果没有看到更多的实现细节,很难说清楚,但我会考虑使用 TestScheduler。在 RxUI.Testing 中,这很简单:
这是一组 MVVM 相关测试的示例,测试番茄钟计时器:
https://github.com/xpaulbettsx/ReactiveUI/blob/master/ReactiveUI.Sample/ReactiveUI.Sample.Tests/ViewModels/BlockTimerViewModelTest.cs
这是基于 MVVM 的测试的另一个很好的示例 来自我的 Rx 书(对插件感到抱歉),特别是使用 CreateColdObservable 来模拟输入(即测试“单击按钮,等待 10 秒,检查结果”的场景)
https://github.com/ProgRx/Chapter-9
It's hard to tell without seeing more implementation details, but I would consider using TestScheduler instead. In RxUI.Testing, this is as easy as:
Here's an example of a bunch of MVVM-related tests, testing a Pomodoro timer:
https://github.com/xpaulbettsx/ReactiveUI/blob/master/ReactiveUI.Sample/ReactiveUI.Sample.Tests/ViewModels/BlockTimerViewModelTest.cs
Here's another good example of MVVM-based testing from my Rx book (sorry about the plug), specifically using CreateColdObservable in order to mock input (i.e. testing the scenario of "Click a button, wait 10 seconds, check result")
https://github.com/ProgRx/Chapter-9