Category Archives: ReactiveUI

Beware an exception in a ReactiveCommand

The Reactive UI class ReactiveCommand can be used to implement a view model’s commands as per the following:

Synchronize = ReactiveCommand.Create(_ => true, DoSynchronize);

This is excellent and works like RelayCommand and DelegateCommand from other MVVM frameworks, in that the first argument of the Create method handles the CanExecute and the second is the Action to be executed when ICommand.Execute is called.

One problem this usage has, is in the case of an exception within the command’s action. As Reactive UI uses Reactive Extensions it also handles errors in the same way.

When an error occurs in Reactive Extensions the default behaviour after an OnError is that subscribers are unsubscibed, in other words no further calls are made to your subscribed Action.

In the case of ReactiveUI’s ReactiveCommand this means if an exception occurs during the Action the command essentially disconnects itself and further commands are ignored. So a simpler way of solving this is to use ReactiveAsyncCommand.

Synchronize new ReactiveAsyncCommand(null);
Synchronize.RegisterAsyncAction(_ => DoSynchronize());

This way a new IObservable is created each time a command is executed, thus an exception will simply stop the current IObservable and the next time the command is called a new one is created.

Unit testing a ReactiveUI ViewModel

This is a quick post about unit testing a view model that uses ReactiveUI. More specifically it’s about testing the MessageBus code within the view model.

So the scenario is simple. I have a view model (of type ConfigurationViewModel) when anything in the application wishes to delete configuration data it sends the appropriate message onto the ReactiveUI MessageBus and the idea is that the configuration view model then correctly calls the delete method on its underlying configuration class. I’m using RhinoMocks to mock the underlying configuration class in the test below.

[Test]
public void DeleteConfiguration_ShouldCallUnderlyingObjectToDeleteProject()
{
   using (mocks.Record())
   {
      Expect.Call(() => configuration.Delete("MyProject"));
   }

   using (mocks.Playback())
   {
      MessageBus.Current.SendMessage(new ProjectViewModel("MyProject", false, false), "Delete");
   }
}

Now this worked perfectly so I happily moved onto another similar test for another part of the configuration. I ran up the tests after implementing the code and one of the tests failed. I ran the single test again now moving from ReSharper’s test runner to NUnit’s. The test passed. I ran all tests and again it failed.

After some reading/searching around I found a post on StackOverflow where Paul Betts mentions the RxApp.DeferredScheduler is exactly that, deferred. After a bit of testing I realised then that I needed to switch this to an ImmediateScheduler to resolve the issues. Once I did this everything worked perfectly.

So the note to myself is to add the code

[SetUp]
public void SetUp()
{
   RsApp.DeferredScheduler = Scheduler.Immediate;

   // setup the mocks etc.
}

A small postscript to the above is that after reading the ReactiveUI code on GITHUB I realised that it attempts to automatically switch the DeferredSchduler to Immediate if it detects it’s being run from a test runner. I removed the above code (in the SetUp) and indeed it all worked fine now. So I’m note quite sure what caused the problem previously, but at least I learned how to solve it if it occurs again.