Tag Archives: reactive extensions

ReactiveUI 6 and ViewModel Testing

Testability and ReactiveUI

ReactiveUI XAML example

In the previous articles about ReactiveUI I’ve claimed without bringing any evidence that writing ViewModels using ReactiveObjects brings about testability. While the aspects of testing Rx and ReactiveUI have been treated at length in the respective authors’ blogs linked herein, this post is intended as a quick glance for the impatient online surfer at the hello-world testing code, which has been written “post-mortem” [1. as in, not within TDD] as a follow-up to the previous articles.

An update to ReactiveUI 6

Paul Betts and contributors have been busy simplifying and extending the library [2. which now also targets Xamarin and Windows Phone 8 and Windows Store Apps]. There are some extension methods now that help creating observables from properties, and transforming observables to properties. In the example ViewModel from previous articles, there’s an observable stream of strings that is simply transformed into a property defined as follows:

ObservableAsPropertyHelper<string> _BackgroundTicker;
public string BackgroundTicker
{
    get { return _BackgroundTicker.Value; }
}

In the constructor, the helper is now initialized without using strings:

public WordCounterModel(IObservable<string> someBackgroundTicker)
{
someBackgroundTicker
    .ToProperty(this, x => x.BackgroundTicker, out _BackgroundTicker);
...
}

instead of string-based error-prone

_BackgroundTicker = new ObservableAsPropertyHelper<string>(
	someBackgroundTicker, _ => raisePropertyChanged("BackgroundTicker")
);

For the actual changes in ReactiveUI, consult Paul Betts’ insightful log.

A simple test

Since the tests have been written after writing the example code, I’ve been searching for the “Generate Unit Test” context menu in Visual Studio 2013. The context menu is not there, but luckily some enthusiasts recreated the functionality partly: → Unit Test Generator.

After the initial set-up and

failedtest

here’s the simple test of the word count property:

[TestMethod]
public void WordCounterModelTest()
{
    var mock = new Mock<IObservable<string>>();
    var vm = new WordCounterModel(mock.Object);

    vm.WordCount.Should().Be(0);

    vm.TextInput = "bla!";
    vm.WordCount.Should().Be(1);

    vm.TextInput = "bla, bla!!";
    vm.WordCount.Should().Be(2);
}

In it, one can observe the use of MOQ for mocking a dummy and FluentAssertions for beautifully readable Spec/BDD-style assertions [3. I originally intended to use SpecFlow, but the specs refused to flow frictionlessly].

So, there’s no UI involved, and the UI is dogmatically bound from XAML with almost no code-behind.

Testing time series

The hello world example program simulated a dependency on some timed series of strings, ticking every second. While this is not specific to ReactiveUI, let’s make use of the test scheduler [4. see Intro to Rx]. For that, the time series should optionally depend on an injected IScheduler:

public class BackgroundTicker
{
    IScheduler scheduler = Scheduler.Default;

    public BackgroundTicker(IScheduler other_scheduler = null)
    {
        if (other_scheduler != null)
            scheduler = other_scheduler;
    }

    public IObservable<string> Ticker
    {
        get
        {
            return Observable
                .Interval(TimeSpan.FromSeconds(1), scheduler)
                .Select(_ => DateTime.Now.ToLongTimeString());
        }
    }
}

The test instantiates a test scheduler, which is then advanced to make deterministic assertions. The code should speak for itself:

[TestMethod]
public void BackgroundTickerTest()
{
    (new TestScheduler()).With(scheduler =>
    {
        var ticker = new BackgroundTicker(scheduler);

        int count = 0;
        ticker.Ticker.Subscribe(_ => count++);
        count.Should().Be(0);

        scheduler.AdvanceByMs(1000);
        count.Should().Be(1);

        scheduler.AdvanceByMs(2000);
        count.Should().Be(3);
    });
}

Summary

passedtest

Code: https://github.com/d-led/reactiveexamples

Previous article: The WPF + ReactiveUI Refactored Version of the Responsive UI Hello World.

See also: the c++ version.

A C++ Background Ticker, now with Rx.cpp

Finally, Rx.cpp

Some time ago I have written that I didn’t have enough patience to recreate the background ticker example in C++ using Rx.cpp. Since then the Rx.cpp project seems to have grown out of the spike phase, and even has a native NuGet package. It has also gone multiplatform (Windows, OSX and Linux): observe the green Travis-CI Button.

Update: new blog post, discussing RxCpp v2 and testing using the test scheduler.

A simple console ticker

As in .Net, Reactive Extensions provide a simple way to process streams of data asynchronously, while keeping the concurrency-related code declarative and thus readable. Here’s a simple ticker in the console which runs asynchronously to the main thread:

auto scheduler = std::make_shared<rxcpp::EventLoopScheduler>();
auto ticker = rxcpp::Interval(std::chrono::milliseconds(250), scheduler);

rxcpp::from(ticker)
	.where([](int val) { return val % 2 == 0; })
	.take(10)
	.subscribe([](int val) {
		std::cout << "tick " << val << std::endl;
	});

std::cout << "starting to tick" << std::endl;

resulting in something like:

starting to tick
tick 0
tick 2
tick 4
tick 6
tick 8
...

where the ticks appear once in 250 milliseconds.

Throwing away code

The PPL example was simulating polling a sensor and printing the value. It had an error-prone and buggy ad-hoc implementation of an active object, ticking at predefined intervals. This can be now happily thrown away, as Rx allows a cleaner concurrency control and testability using schedulers, and implements a timed sequence: Interval.

Preconditions

FrequencyMeter FM;
auto scheduler = std::make_shared<rxcpp::EventLoopScheduler>();

The scheduler will be used for all subscriptions.

The tickers

The first one:

auto measure = rxcpp::Interval(std::chrono::milliseconds(250),scheduler);
auto measure_subscription = rxcpp::from(measure)
	.subscribe([&FM](int val) {
		std::cout << FM.Hz() << std::endl;
	});

where measure_subscription is a rxcpp::Disposable for subscription lifetime control.

And the other one:

auto ticker = rxcpp::Interval(std::chrono::milliseconds(500), scheduler);
rxcpp::from(ticker)
	.take(10)
	.subscribe([](int val) {
		std::cout << "tick " << val << std::endl;
	});

where you can observe the LINQ-style filter take

Managing subscriptions

In the PPL example, one could start and stop the ticker. However, in Rx.cpp this can be simply modeled by disposable subscriptions. Hence, after some kind of sleeping, the measurement can be stopped:

sleep(2000);
std::cout << "Canceling measurement ..." << std::endl;
measure_subscription.Dispose(); // cancel measurement

Resulting in similar output:

60
63
tick 0
61
62
tick 1
63
63
tick 2
62
60
tick 3
Canceling measurement ...
tick 4
tick 5
tick 6
tick 7
tick 8
tick 9

Restarting measurement can be done by creating a new subscription.

Why not simply signals/slots?

Almost quoting the Intro to Rx book, the advantages of using Rx over (at least) simple implementations of signal/slot mechanism are:

  • Better maintainability due to readable, composable, declarative code
  • Scheduler abstraction allowing for fast, deterministic, clock-independent tests of concurrency concerns
  • Declarative concurrency through the same scheduler abstraction
  • LINQ-like composition and filtering of event streams
  • Easy subscription control via disposables
  • Completion and exception handling built-in in the Observer concept

Code

@GitHub

Corrections, suggestions and comments are welcome!

Update 26.6.2014: There’s been a new release of Rx.cpp on nuget, and Kirk Shoop pushed a pull request, upgrading the project and the api usage to Rx.cpp 2.0.0. There have been some changes, and there are some interesting patterns, which should be blogged about in the near future.

The WPF + ReactiveUI Refactored Version of the Responsive UI Hello World

Overview

To recapitulate, the first article in the series used Reactive Extensions (Rx) directly in Windows Forms UI logic to implement a UI with a simulated background calculation, which delivered a timestamp each second. The rest of the application was an input text box, for which, when the user inputs the text, the word count is calculated asynchronously and posted into another read-only text box.

The second article introduced a WPF version of the same UI with a viewmodel that implements the INotifyPropertyChanged interface and supplies the ticker text and the word count as bindable properties. The text being input was delivered to the viewmodel via an event converted to an observable sequence, which was used to update the TextInput property of the viewmodel. The WordCount was updated from the setter of TextInput.

The third article recreated the WPF implementation in WinForms using the same viewmodel, which is shared between the two projects. The third UI implementation introduced throttling of the TextInput changes to 0.3 seconds so that the word count is updated only when the user pauses for at least a third of a second to take a look at the result.

The Refactored WPF Version

In this article, the WPF UI is further refactored, so that the concerns are separated further. These are organized as follows:

Create a sequence of some calculation results

These are timestamps in this case, implemented as an object, providing an IObservable<string> property Ticker:

public class BackgroundTicker
{
    public IObservable<string> Ticker
    {
        get
        {
            return Observable
                .Interval(TimeSpan.FromSeconds(1))
                .Select(_ => DateTime.Now.ToLongTimeString());
        }
    }
}

The observable sequence is active, delivering a value every second.

Count words in text asynchronously and provide another property calculated in the background

This viewmodel is finally implemented using ReactiveUI:

public class WordCounterModel : ReactiveObject

The word count and the input text are ReactiveUI boilerplate:

string _TextInput;
public string TextInput
{
    get { return _TextInput; }
    set { this.RaiseAndSetIfChanged(ref _TextInput, value); }
}

ObservableAsPropertyHelper<int> _WordCount;
public int WordCount
{
    get { return _WordCount.Value; }
}

The value sequence of the background ticker is injected at construction time using its observable member. The word count and the background ticker properties are implemented using an ObservableAsPropertyHelper.
The results of the background ticker are exposed via a property:

ObservableAsPropertyHelper<string> _BackgroundTicker;
public string BackgroundTicker
{
    get { return _BackgroundTicker.Value; }
}

the helper is initialized from the constructor-supplied observable:

someBackgroundTicker
    .ToProperty(this, ticker => ticker.BackgroundTicker, out _BackgroundTicker);

And finally, the word count logic is implemented as an output property, transforming the sequence of strings into a sequence of integers:

this.WhenAnyValue(x => x.TextInput)
    .Where(x => !string.IsNullOrWhiteSpace(x))
    .Select(x => x
        .Split()
        .Where(word => !string.IsNullOrWhiteSpace(word))
        .Count())
    .ToProperty(this, vm => vm.WordCount, out _WordCount);

The throttling can be removed from the viewmodel, as the WPF 4.5 has a Delay binding property, which can be used for the same purpose on the view side, freeing the viewmodel from that concern.

Provide a Graphical UI

Now let’s look at the view. The event subscription is gone and data binding is implemented in XAML declaratively. The DataContext of the main window is initialized with an instance of the viewmodel, which is initialized with an observable from an instance of a background ticker:

ViewModels.BackgroundTicker Ticker=new ViewModels.BackgroundTicker();
ViewModels.WordCounterModel VM = new ViewModels.WordCounterModel(Ticker.Ticker);
DataContext = VM;

This instantiation can be definitely made in XAML as well, nullifying the amount of C# code for the view, as for example in the following article.

The background ticker and the word count are now bound one-way and marked asynchronous.

<TextBox ... Text="{Binding BackgroundTicker,IsAsync=True,Mode=OneWay}"></TextBox>
<TextBox ... Text="{Binding WordCount,IsAsync=True,Mode=OneWay}"></TextBox>

And finally, the binding of the input text is configured in XAML to be throttled to 300 milliseconds and bind on PropertyChanged events of the Text property of the text box:

<TextBox ... Text="{Binding TextInput, UpdateSourceTrigger=PropertyChanged, Delay=300}"></TextBox>

Source Code

https://github.com/d-led/reactiveexamples