Hi Folks,
As most of you who’re familiar with my work know – I’m a huge supporter of the open source community.
I also hold firm to a belief that the Microsoft .Net ecosystem is truly great due to community and vendors innovation.
During this article I’d like for us to go over 4 open source initiatives: The Microsoft’s Silverlight Unit Testing framework, RhinoMocks , Microsoft Unity and the Silverlight unit testing plug-in for Resharper.
Here are some links to get you started:
1. Microsoft Silverlight Unit testing framework
2. RhinoMocks
3. Microsoft Unity
4. Silverlight Unit Test Runner for Resharper
You can grab the application we’ve developed from: SL2_UnitTestingRhinoMocksUnityResharper.zip
The obligatory Hello World sample
In order to introduce these 4 unit testing oriented projects we’ll start of from the canonical hello world sample.
After that we’ll move to something a bit more Interesting.
We’ll start a new Silverlight project which we’ll for our sample:
We’ll use a Textblock with “Hello World!” as text:
<TextBlock Text="Hello World!" x:Name="txt" x:FieldModifier="public" />
When we run our application we’ll see:
Microsoft Silverlight Unit Testing framework – “Hello World”
Since Silverlight can’t load Desktop .Net CLR assemblies and the Desktop CLR can’t load Silverlight controls – We can’t use existing unit testing frameworks.
So, no MbUnit, no NUnit, no xUnit. Sad.
In comes developer extraordinaire Jeff Wilcox and develops the Microsoft Silverlight Unit testing framework.
1. Download the latest Binaries from Microsoft Silverlight Unit Test Framework.
2. Create a project used for unit testing.
3. Add a reference to the 2 Unit testing DLLs to our testing project.
4. From the testing project we’ll add a reference to the runtime project.
5. Set your Application.Root in App.xaml.cs to a unit testing runner:
namespace SL2_UnitTestingRhinoMocksUnityRes_Tests
{
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = UnitTestSystem.CreateTestPage();
}
Now we’ve got a basic unit testing project setup.
Next, we’ll create a new class to test our actual Silverlight “Page” class.
And we’ll put the appropriate attributes to run a test:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SL2_UnitTestingRhinoMocksUnityResharper;
namespace SL2_UnitTestingRhinoMocksUnityRes_Tests
{
[TestClass]
public class Page_Tests : SilverlightTest
{
[TestMethod]
public void Page_Initialized_ShouldHaveAextBlock()
{
Page page = new Page();
Assert.IsTrue(???);
}
}
}
In this test, we’d like to make sure that when Page has been initialized. And there is indeed a textblock with the Text hello world in there.
The problem with that is that we’ll need to add Page to the visual tree and wait for the loaded event.
Well, we can’t do that from a synchronous test. We’ll have to use an Async test format.
[TestMethod]
[Asynchronous]
public void Page_Initialized_ShouldHaveATextBlock()
{
Page page = new Page();
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => Assert.IsTrue(page.txt != null));
EnqueueTestComplete();
}
Let’s go line by line here.
We’ll declare an async test method.
[TestMethod]
[Asynchronous]
public void Page_Initialized_ShouldHaveATextBlock()
We’ll create a new page class to be tested.
We’ll wait for the Page.Loaded event after it has been added to the visual tree.
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
Next, we’ll tell the async testing engine that “after loaded has happened” we need to check if the page.txt public field (the TextBlock) has been initialized.
EnqueueCallback(() => Assert.IsTrue(page.txt != null));
And than we’ll tell the async testing engine that we’re done testing.
When we run our testing project we’ll see this:
Now, I’d like to confess that the “WaitFor” method isn’t something the comes with the Silverlight unit testing framework. It’s a little helper method I use.
Here’s the syntax, though it’s not important:
protected void WaitFor<T>(T objectToWaitForItsEvent, string eventName)
{
EventInfo eventInfo = objectToWaitForItsEvent.GetType().GetEvent(eventName);
bool eventRaised = false;
if (typeof(RoutedEventHandler).IsAssignableFrom(eventInfo.EventHandlerType))
eventInfo.AddEventHandler(objectToWaitForItsEvent, (RoutedEventHandler)delegate { eventRaised = true; });
else if (typeof(EventHandler).IsAssignableFrom(eventInfo.EventHandlerType))
eventInfo.AddEventHandler(objectToWaitForItsEvent, (EventHandler)delegate { eventRaised = true; });
EnqueueConditional(() => eventRaised);
}
There are plans to address the need for a WaitFor method in one form or another in future versions of the unit testing framework.
Next, we’d like to test that the TextBlock has the correct text.
[TestMethod]
[Asynchronous]
public void PageWithTextBlock_Initialized_ShouldHaveHelloWorldText()
{
Page page = new Page();
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => Assert.IsTrue(page.txt.Text == "Hello World!"));
EnqueueTestComplete();
}
And if we can run our test we’ll see that this test succeeded:
RhinoMocks – Hello World
1. Download RhinoMocks for silverlight.
2. Add a reference to these files from the Testing project:
As we move more towards real-world examples we need better tools to handle testing.
We’ll start off by creating a ViewModel for page:
public class PageViewModel
{
private string _helloText = "Hello World!";
public virtual string HelloText
{
get { return _helloText; }
set { _helloText = value; }
}
}
It’s important to note that this is not a ViewModel article and I’m not following best MVVM practices.
MVVM and Unit testing are complimentary. but in the interest of keeping this article simple I’ll keep the ViewModel simple.
Next, we’ll create a ViewModel property on Page:
public partial class Page : UserControl
{
private PageViewModel _viewModel = new PageViewModel();
public PageViewModel ViewModel
{
get { return _viewModel; }
set { _viewModel = value; }
}
public Page()
{
InitializeComponent();
}
}
And we’ll set the Page.DataContext to the ViewModel.
public partial class Page : UserControl
{
private PageViewModel _viewModel = new PageViewModel();
public PageViewModel ViewModel
{
get { return _viewModel; }
set { _viewModel = value; }
}
public Page()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = ViewModel;
}
}
Let’s run our tests first to make sure we didn’t break anything:
We didn’t break anything, we’re good.
Now, let’s add another test class for PageViewModel.
[TestClass]
public class PageViewModel_Tests : SilverlightTest
{
[TestMethod]
public void PageViewModel_ByDefault_ShouldHaveHelloWorldTest()
{
PageViewModel pageViewModel = new PageViewModel();
Assert.IsTrue(pageViewModel.HelloText == "Hello World!");
}
}
And we’ll run our tests:
All green.
Now it’s time to hook up our TextBlock to the ViewModel.
<UserControl x:Class="SL2_UnitTestingRhinoMocksUnityResharper.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock x:Name="txt" x:FieldModifier="public" Text="{Binding HelloText}" />
</Grid>
</UserControl>
And let’s run our test again to make sure everything still works:
Now, we’d like to test that PageViewModel.HelloText does get invoked by Page.
Finally, we can use RhinoMocks.
Here’s one way to write that test:
[TestMethod]
[Asynchronous]
public void Page_Loaded_ShouldUsePageViewModelHelloTextOnce()
{
Page page = new Page();
page.ViewModel = new PageViewModel() { HelloText = "Bonjour Monde!" };
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => Assert.IsTrue(page.txt.Text == "Bonjour Monde!"));
EnqueueTestComplete();
}
Right now this test would run, but it has 2 main issues:
1. We’re testing PageViewModel when really we want to test Page invoking PageViewModel.
2. We’re testing the entire Page Lifecycle in the UI, which we don’t want to do.
This test is supposed to test the red arrow “Invokes”, but instead we’re testing this entire diagram.
Which makes our test brittle and poorly written.
Let’s write a test that only checked the “Invokes” arrow.
[TestMethod]
[Asynchronous]
public void Page_Loaded_ShouldUsePageViewModelHelloTextOnce()
{
Page page = new Page();
MockRepository mocks = new MockRepository();
PageViewModel pageViewModel = (PageViewModel) mocks.StrictMock(typeof(PageViewModel));
page.ViewModel = pageViewModel;
using(mocks.Record())
{
pageViewModel.Expect(p => p.HelloText).Return(string.Empty);
}
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => mocks.VerifyAll());
EnqueueTestComplete();
}
Let’s go line-by-line here.
MockRepository mocks = new MockRepository();
PageViewModel pageViewModel = (PageViewModel) mocks.StrictMock(typeof(PageViewModel));
We’ve initialized a mock repository which is a magical doohickey that creates mocks and checks expectations.
We used it to create a mock for PageViewModel.
using(mocks.Record())
{
pageViewModel.Expect(p => p.HelloText).Return(string.Empty);
}
We’ve recorded an expectation that someone should invoke PageViewModel.HelloText. (And it should return a String.Empty)
EnqueueCallback(() => mocks.VerifyAll());
And in the end of the test, in stead of checking the UI we’ll check the expectation have been met.
Let’s run our test:
And now let’s run it again if we temporarily delete the binding:
<TextBlock x:Name="txt" x:FieldModifier="public" Text="{Binding HelloText}" Text="Hello World!" />
We can clearly see that if the PageViewModel.HelloText property’s getter isn’t called, RhinoMocks will fail the test.
Let’s add another test to test the whole workflow without testing the PageViewModel itself:
[TestMethod]
[Asynchronous]
public void Page_Loaded_ShouldUsePageViewModelHelloTextInTextBlock()
{
Page page = new Page();
MockRepository mocks = new MockRepository();
PageViewModel pageViewModel = (PageViewModel)mocks.StrictMock(typeof(PageViewModel));
page.ViewModel = pageViewModel;
using (mocks.Record())
{
pageViewModel.Expect(p => p.HelloText).Return("Bonjour Monde!");
}
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => Assert.IsTrue(page.txt.Text == "Bonjour Monde!"));
EnqueueCallback(() => mocks.VerifyAll());
EnqueueTestComplete();
}
And again, all of our tests pass:
The advantage of testing with Mocks – we test only what we need to test – we didn’t the actual PageViewModel class in this test.
Microsoft Unity – Hello World
Unity is an Inversion of Control framework which let’s us easily reduce the complexity of our object model.
Big words, eh? Let’s get down to the code.
1. Download and install Unity for Silverlight.
2. Add references to the Unity DLL to both our runtime and testing project.
Now, we’ll remove the Page.ViewModel property.
public partial class Page : UserControl
{
private PageViewModel _viewModel = new PageViewModel();
public PageViewModel ViewModel
{
get { return _viewModel; }
set { _viewModel = value; }
}
And we’ll add a property that will get automatically populated by Unity:
public partial class Page : UserControl
{
[Dependency]
public PageViewModel ViewModel { get; set; }
Basically the [DependencyAttribute] says “Hey, Unity! I’m here! put a value into this property.”
Now, we’ll create a static IoC used from everywhere in our App:
public static class IoC
{
static IoC()
{
Current = new UnityContainer();
}
public static UnityContainer Current { get; set; }
}
In our runtime project App.xaml.cs we’ll register “PageViewModel” type as the correct type to fill for any property of type PageViewModel.
public static class IoC
{
static IoC()
{
Current = new UnityContainer();
Current.RegisterType<PageViewModel, PageViewModel>();
}
public static UnityContainer Current { get; set; }
}
Not the best of examples, I’ll admit that. But if we used a IPageViewModel this piece of code would have more meaning, and would look like this:
public static class IoC
{
static IoC()
{
Current = new UnityContainer();
Current.RegisterType<IPageViewModel, PageViewModel>();
}
public static UnityContainer Current { get; set; }
}
Which basically tells “Hey, Unity! Whenever you need to fill a property of type IPageViewModel use PageViewModel.”
Since we’re not using such an interface, we’ll go back to the original syntax.
One last thing we have to do is tell Unity to populate our type:
public partial class Page : UserControl
{
[Dependency]
public PageViewModel ViewModel { get; set; }
public Page()
{
InitializeComponent();
IoC.Current.BuildUp(this);
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = ViewModel;
}
}
Now, let’s run our app:
It still shows “Hello world!”.
Let’s go over how that happened:
How does that help us write better code?
Well, right now we only have a dependency between 2 classes. So it doesn’t help us a lot.
Becomes:
But when dealing with real-world object graphs with a more complicated Object graph it becomes obvious why IoC containers are good:
When using IoC containers:
In a real-world app, everyone registers with the IoC container and resolve dependencies with it.
Now, let’s use Unity in on our unit tests and re-write our existing tests to use Unity to resolve these dependencies:
[TestMethod]
[Asynchronous]
public void Page_Loaded_ShouldUsePageViewModelHelloTextOnce()
{
Page page = new Page();
MockRepository mocks = new MockRepository();
PageViewModel pageViewModel = (PageViewModel) mocks.StrictMock(typeof(PageViewModel));
page.ViewModel = pageViewModel;
using(mocks.Record())
{
pageViewModel.Expect(p => p.HelloText).Return(string.Empty);
}
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => mocks.VerifyAll());
EnqueueTestComplete();
}
we’ll re-write the test to use our Unity container:
[TestMethod]
[Asynchronous]
public void Page_Loaded_ShouldUsePageViewModelHelloTextOnceWithUnity()
{
MockRepository mocks = new MockRepository();
IoC.Current.RegisterInstance(typeof(PageViewModel), mocks.StrictMock(typeof(PageViewModel)));
Page page = IoC.Current.Resolve<Page>();
using (mocks.Record())
{
IoC.Current.Resolve<PageViewModel>().Expect(p => p.HelloText).Return(string.Empty);
}
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => mocks.VerifyAll());
EnqueueTestComplete();
}
Let’s go line-by-line here:
IoC.Current.RegisterInstance(typeof(PageViewModel), mocks.StrictMock(typeof(PageViewModel)));
Basically we’re telling Unity that whenever it needs to resolve PageViewModel it should use a PageViewModel mock from RhinoMocks.
Page page = IoC.Current.Resolve<Page>();
Instead of initializing a type with “new myClass();” we’re using Unity to get a class that has all of it’s dependencies resolved. In our case, a Page with a PageViewModel Mock.
using (mocks.Record())
{
IoC.Current.Resolve<PageViewModel>().Expect(p => p.HelloText).Return(string.Empty);
}
In stead of keeping a local copy of the Mock we created for Unity, we’re using Unity’s Resolve method to test get the mock back.
And when we run our tests:
Let’s rewrite this test with Unity:
[TestMethod]
[Asynchronous]
public void Page_Loaded_ShouldUsePageViewModelHelloTextInTextBlock()
{
Page page = new Page();
MockRepository mocks = new MockRepository();
PageViewModel pageViewModel = (PageViewModel)mocks.StrictMock(typeof(PageViewModel));
page.ViewModel = pageViewModel;
using (mocks.Record())
{
pageViewModel.Expect(p => p.HelloText).Return("Bonjour Monde!");
}
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => Assert.IsTrue(page.txt.Text == "Bonjour Monde!"));
EnqueueCallback(() => mocks.VerifyAll());
EnqueueTestComplete();
}
Becomes:
[TestMethod]
[Asynchronous]
public void Page_Loaded_ShouldUsePageViewModelHelloTextInTextBlockWithUnity()
{
MockRepository mocks = new MockRepository();
IoC.Current.RegisterInstance(typeof(PageViewModel), mocks.StrictMock(typeof(PageViewModel)));
Page page = IoC.Current.Resolve<Page>();
using (mocks.Record())
{
IoC.Current.Resolve<PageViewModel>().Expect(p => p.HelloText).Return("Bonjour Monde!");
}
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => Assert.IsTrue(page.txt.Text == "Bonjour Monde!"));
EnqueueCallback(() => mocks.VerifyAll());
EnqueueTestComplete();
}
And when we run our tests:
Some slight of hand I used here is to change this test:
[TestMethod]
[Asynchronous]
public void PageWithTextBlock_Initialized_ShouldHaveHelloWorldText()
{
Page page = IoC.Current.Resolve<Page>(); //new Page();
WaitFor(page, "Loaded");
TestPanel.Children.Add(page);
EnqueueCallback(() => Assert.IsTrue(page.txt.Text == "Hello World!"));
EnqueueTestComplete();
}
We no longer initialize types with “new” rather through the IoC container.
And I added this Piece of code to initialize our IoC between each test:
[TestInitialize]
public void Init()
{
IoC.Current = new UnityContainer();
}
Silverlight Unit Test Runner for Resharper – Hello World
Running our tests breaks the flow of development.
We have to exit Visual studio, run the test harness and wait for it to run.
In comes Einar Ingebrigtsen’s Resharper SIlverlight Unit test runner.
1. Install R# (Resharper) from http://www.jetbrains.com/resharper/download/index.html
R# is a commercial plugin for Visual studio, but has 30 first days free.
2. Download the latest version of the R# Silverlight Unit test runner from Einar’s blog.
3. Drag & Drop the 3 DLLs into the machine’s GAC. (On my computer at: c:\Windows\Assembly)
4. Copy the 3 DLLs and the “Website” directory into a subdirectory under the Resharper plugin directory.
(On my computer: C:\Program Files\JetBrains\ReSharper\v4.1\Bin\Plugins\C:\Program Files\JetBrains\ReSharper\v4.1\Bin\Plugins\)
5. Restart Visual studio and when prompted for a website address put in the file path for the ‘website’ directory.
with our testing project open, open up the Resharper Unit Testing explorer.
And you can see our 7 Silverlight unit tests In the R# Unit test explorer.
We’ll press the “run” button to run all the tests.

A new R# Test session starts up and we’ll have to wait 5 seconds the first time for tests to start running.

And we can see that all test pass:
And finally, it’s just easier to run our tests by pressing “Run all tests from solution” (and maybe assigning a shortcut for it).
Summary – Hello World
Hopefully this short blog post is enough to get you on your way in the exciting world of unit testing.
None of these solutions are the sole frameworks in their respective field, but they are a good start.
The article doesn’t talk about best practices like Unity AutoMocker or ViewModels, but it does give you a good start.
I’ll try to cover other Silverlight IoC containers and Silverlight Mocking solutions in future blog posts.
Sincerely,
-- Justin Angel
Microsoft Silverlight Toolkit Program Manager