ReactiveUI MessageBus 和 MessageBox 以及结果

发布于 2024-12-17 12:49:15 字数 1081 浏览 1 评论 0原文

我在一个项目中使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

百思不得你姐 2024-12-24 12:49:15

如果没有看到更多的实现细节,很难说清楚,但我会考虑使用 TestScheduler。在 RxUI.Testing 中,这很简单:

(new TestScheduler()).With(sched => {
    // Write your test here, all the schedulers will be
    // implicitly set to your 'sched' scheduler.
});

这是一组 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:

(new TestScheduler()).With(sched => {
    // Write your test here, all the schedulers will be
    // implicitly set to your 'sched' scheduler.
});

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文