Unit Testing in silverlight land with Typemock Isolator - ISerializable - Roy Osherove's Blog

Unit Testing in silverlight land with Typemock Isolator

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:

  1. You have an open solution
  2. the solution contains a silverlight class library or silverlight application project

To setup a test project against silverlight using MSTest:

  1. Add a new test project to the solution
  2. Remove all the existing classes (Database test, ordered test etc..) so that you are only left with the unit test class (UnitTest1).
  3. 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)
  4. 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)
  5. Add a reference to the project under test
  6. You can now write tests against the object model (standard classes)

 

To setup a test project against silverlight using NUnit or MbUnit:

  1. Add a new class library to the solution as your test project
  2. 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)
  3. Add a reference to the project under test
  4. 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:

WindowClipping

 

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:

  1. In your test project add two references under the .NET tab: “Typemock Isolator” and “Typemock ArrangeActAssert”
  2. Write the following test:

WindowClipping (2)

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:

WindowClipping (3)

 

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:

WindowClipping (4)

There are several things to note here:

  1. 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.
  2. 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)
  3. 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.

Published Saturday, December 27, 2008 4:54 PM by RoyOsherove

Comments

Sunday, December 28, 2008 3:05 AM by Scott Bellware

# re: Unit Testing in silverlight land with Typemock Isolator

Specifically, those dependencies aren't broken - they're intercepted.  It's not entirely disingenuous to say that dependencies are broken, but the "break dependencies" terminology colloquially refers to a design activity rather than such a brute force countermeasure.

Sunday, December 28, 2008 5:51 PM by stevevrporter

# re: Unit Testing in silverlight land with Typemock Isolator

Wow, very timely. I have a spike to work on just this very item. Thanks.

Saturday, January 03, 2009 12:10 PM by stevevrporter

# re: Unit Testing in silverlight land with Typemock Isolator

Looks like Visual Studio has a bit of a issue with the code coverage feature and Silverlight applications. The test run config dialog disappears when you click on the code coverage list item.

Monday, March 09, 2009 8:44 PM by Chandra Gottumukkala

# re: Unit Testing in silverlight land with Typemock Isolator

Roy,

I was trying to run NUnit test from NUnit GUI.

I received invalid thread access exception. It looks like the NUnit thread is not able to access the Silverlight UI thread for some reason. How to overcome this crossthread access issue?

Your help would be appreciated.

Exception details:

Tests.UnitTest1.TestMethod1:

System.TypeInitializationException : The type initializer for 'System.Windows.DependencyObject' threw an exception.

 ----> System.UnauthorizedAccessException : InvalidCrossThreadAccess

-----

at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex)

at System.Windows.UIElement..ctor(UInt32 nKnownTypeIndex)

at System.Windows.FrameworkElement..ctor(UInt32 nKnownTypeIndex)

at System.Windows.Controls.Control..ctor(UInt32 nKnownTypeIndex)

at System.Windows.Controls.UserControl..ctor()

at CheckFree.ConsumerBanking.AccountDetailsControl..ctor() in C:\dev\SLProject\WintellectLatest\ConsumerBanking\AccountDetailsControl.xaml.cs:line 11

at Tests.UnitTest1.TestMethod1() in C:\dev\SLProject\WintellectLatest\Tests\UnitTest1.cs:line 26

at TypeMock.MockManager.a(String A_0, String A_1, Object A_2, Object A_3, Boolean A_4, Object[] A_5)

at TypeMock.InternalMockManager.getReturn(Object that, String typeName, String methodName, Object methodParameters, Boolean isInjected)

at Tests.UnitTest1.TestMethod1() in C:\dev\SLProject\WintellectLatest\Tests\UnitTest1.cs:line 22

--UnauthorizedAccessException

at MS.Internal.XcpImports.CheckThread()

at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)

at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex)

at System.Windows.DependencyObject..ctor()

at System.Windows.DependencyObject.ManagedReferencesToken..ctor()

at System.Windows.DependencyObject..cctor()

------

I wrote one sample test like below:

namespace Tests

{

/// <summary>

/// Summary description for UnitTest1

/// </summary>

[TestFixture]

public class UnitTest1

{

[Test, Isolated]

public void TestMethod1()

{

Isolate.WhenCalled(() => App.IsDesignTime()).WillReturn(true);

AccountsControl accountsControl = new AccountsControl();

Assert.IsNotNull(accountsControl);

}

}

}

Tuesday, March 10, 2009 6:02 AM by RoyOsherove

# re: Unit Testing in silverlight land with Typemock Isolator

Chandra :

that is because the NUNIT gui was not running with Typemock Isolator enabled on it's process.

either run "TmockRunner.exe  nunitgui.exe" which will enable this, or start Nunit from within visual studio (if you have testdriven .net you can right click on the test project and select test with->nunit"

Tuesday, March 10, 2009 2:23 PM by Chandra

# re: Unit Testing in silverlight land with Typemock Isolator

It did not solve the issue.

Now, I also commented the typemock code and tried to run NUnit from visual studio as well.

It throws the same exception.

Invalid Cross Thread access.

I think the Nunit is running on different thread from Silverlight UI.  So, it is complaining.  Do I need to add any configuration file into my silverlight project so that Nunit tests will have access to silverlight thread?

--Chandra

Tuesday, March 24, 2009 6:34 PM by Chandra

# re: Unit Testing in silverlight land with Typemock Isolator

Roy sent me the CThru that was built with TypeMock5.2.3. When I used this CThru 5.2.3 alogn with TypeMock5.2.3, it has resolved the CrossThread access issue. Now, the silverlight calls are being intercepted successfully when UnitTests were executed.

Thanks to Roy. I apprecieate your help.

I hope it would help somebody else too who might face this issue.

--Chandra