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 в пользовательском интерфейсе и в своих тестах.

Все это прекрасно работает при запуске приложения, но в модульных тестах, поскольку шина затем использует планировщик Immediate, очевидно, что это не работает так же.

Я чувствую, что здесь есть какой-то дизайнерский сбой, поэтому любой вклад в реальную проблему; чтобы показать окно сообщения, возвращающее результат, который можно проверить, было бы очень признательно!


person lbergnehr    schedule 22.11.2011    source источник


Ответы (1)


Трудно сказать, не видя дополнительных деталей реализации, но вместо этого я бы подумал об использовании TestScheduler. В RxUI.Testing это так же просто, как:

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

Вот пример набора тестов, связанных с MVVM, для тестирования таймера Pomodoro:

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

person Ana Betts    schedule 24.11.2011
comment
Хорошая идея, я попробую TestScheduler для этой конкретной проблемы. Что еще вы думаете об этом способе получения результата из диалогового окна? Как вы это делаете при использовании ReactiveUI? Я полагаю, это сводится к тому, что MessageBus откладывается, а не немедленно, как это имеет место, например. MVVMLight, не так ли? - person lbergnehr; 24.11.2011