Writing Asynchronous Tests with Rx and Silverlight
Integration testing in Silverlight is hard. Pretty much any kind of external service is going to require an asynchronous call that returns on the UI thread. And unlike most unit testing frameworks, the one used for Silverlight runs on the same said thread so you cannot block it while waiting for the service call to return.
To make matters worse, the de facto testing framework for Silverlight, known simply as the Silverlight Unit Testing Framework, is very brittle. An unhandled exception on any thread will crash the entire test run, and as mentioned before, integration tests require multi-threading.
One solution to this is to always use EnqueueCallback to ensure that exceptions are properly reported to the unit testing framework. However this too can be difficult to get right and it only takes one mistake to disrupt all of the following tests. Richard Szalay is demonstrates how Reactive Extensions can be used to augment asynchronous testing while at the same time make it less error prone.
The techniques used by Richard assume that you are using the asynchronous pattern with the traditional Begin and End methods. The Observable.FromAsyncPattern function is used to wrap the service call in an IObservable. Once that is done the ObserveOnTest function attaches the unit test framework to the call chain via a specialized scheduler called the WorkItemTestScheduler. Finally the Subscribe function is called to kick off the sequence and evaluate the result.
Rx can represent anything asynchronous, including completely custom sources. The code I posted on my blog simply marshals messages from any Rx source back to the MSTest stack so exceptions can be caught by it.
Chris Mattmann Apr 15, 2014