I’ve been asked quite a lot recently whether one can write unit tests and isolate logical code that runs inside a silverlight application. Up until today my initial answer was ‘no’ because silverlight runs under different versions of mscorlib.dll.
however.
Today I actually gave it a try and realized that writing unit tests (not integration tests, as the silverlight test framework allows) against silverlight based code is possible and quite easy. Just like any other code that relies on a third party platform (like sharepoint code) the silverlight related code might have various dependencies.
I’m going to show how to use Typemock Isolator to overcome a couple of simple silverlight dependencies (using HtmlPage) and how to setup a test project against a silverlight project (with NUnit or MsTest)
Assumptions:
- You have an open solution
- the solution contains a silverlight class library or silverlight application project
To setup a test project against silverlight using MSTest:
- Add a new test project to the solution
- Remove all the existing classes (Database test, ordered test etc..) so that you are only left with the unit test class (UnitTest1).
- Remove all useless comments and crud code from the test class so that you are only left with a test method (no comments, not even the TestContext)
- Add a reference to the silverlight versions of “System.dll”, “System.Windows.dll” to the test project. (usually located under “C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies\” (remove existing reference to system.dll if you need to first)
- Add a reference to the project under test
- You can now write tests against the object model (standard classes)
To setup a test project against silverlight using NUnit or MbUnit:
- Add a new class library to the solution as your test project
- Add a reference to the silverlight versions of “System.dll”, “System.Windows.dll” to the test project. (usually located under “C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies\” (remove existing reference to system.dll if you need to first)
- Add a reference to the project under test
- You can now write tests against the object model (standard classes)
How to break the dependencies
Now, here is a simple example of code that has a silverlight dependency we’d like to test:
Let’s say we have a class in the silverlight project called ChatSession (I’m basing this on ScottGu’s Chat demo). but it’s constructor looks like this:
What if we wanted to control during our test whether the page is enabled or disabled?
Here’s one way to do it using Isolator:
- In your test project add two references under the .NET tab: “Typemock Isolator” and “Typemock ArrangeActAssert”
- Write the following test:
Using Isolate.WhenCalled() we are able to circumvent any method (static or not) to return whatever we want, or throw an exception.
Here’s a more interesting case. Let’s say we have a method that modifies the current page and shows some html to the user in a span tag:
here is one way to write a test that makes sure that the right text is set into the message element in the page, without needing to have a real page present:
There are several things to note here:
- HtmlElement is Sealed has an internal constructor, but we can still create a fake instance of it using Isolator. None of the other frameworks can do this.
- We are returning a fake object from a method call chain (HtmlPage.Document.GetElementById ) without needing to create a separate stub for document. None of the other frameworks can do this (especially since it is based on a static method call to begin with)
- We assert in the end that the method was indeed called with the correct arguments without needing to change a single piece of code. Granted, I wouldn’t write code like this (I like decoupling!) but sometimes you just don’t have the ability to change existing code.
If you are developing an open source silverlight project, it is important to note that there is a free full version of isolator for open source projects with full functionality.
These are just the beginning of my journey into silverlight unit testing. I’m looking for good code examples that you might want to test, with various dependencies that need breaking. your comments are appreciated.