Thursday, 10 March 2011

Unit Testing for SharePoint 2010 - Part 2

Part 1 of Unit Testing for SharePoint 2010

Overview:  Part 1 discusses setting up nUnit and TDD.NET on you dev machine and writing a simple unit test.  This post looks at using TypeMock Isolator to unit test SharePoint dependent code.
Background:  I haven't used TypeMock Isolator in the last 2 years but the latest version still is a good candidate for testing SharePoint 2010 based applications.   The TypeMock Isolator allows you to fake calls to SharePoint so that you can run unit testing against the SharePoint object model with actually having SharePoint installed or going to a specific instance of SharePoint 2010.  The full version (i.e. not the SharePoint only version of TypeMoch Isolator) also allows you to do create isolation mocks of you code (see Rhino Mocks is a good Isolator Framework).  So pretty useful for testing SharePoint or Entity Framework.  You simply mock out the expected behaviour and don't need to test the Entity Framework by connecting to it.

Tip:  You can use this exact same technique to test MOSS.
Tip: TypeMock needs a separate build server licence from the developer licences.  You can use the full product that includes the ability to do SharePoint testing or just the SharePoint TypeMock isolator.  As of 6 March 2011 the SharePoint edition costs 249 euros per year.  Licencing is expensive especially for large dev teams with multiple build servers but the returns are good if your organisation buys into TDD.
Tip: The SharePoint edition is fine for testing SharePoint calls but you can't mock your own .NET methods so you can't simply use a factory pattern and then mock your entire .NET method call as was shown to me by Ketul Patel (@Pateketu).

Objectives: Create a unit test that uses TypeMock Isolator that mocks the call to SharePoint.
TypeMock to Isolate a method call:
Add 4 reference for nUnit and TypeMock frameworks.
Add a reference to the library you are testing in my case "MagicBall.dll".
Create a new unit test, I isolate a call to the method "GetSPQuestions" and return a list of strings (this has allowed me to override the normal call that would be made to SharePoint).
My business logic for the "Magic 8 Ball" is shown below.  The key take away is I fake the method call GetSPQuestions() using TypeMock so it doesn't try access SharePoint.  This allows me to test my business logic using SharePoint's object model.
TypeMock to Isolate a SharePoint call:
The previous technique works if the return data is not SharePoint objects, so TypeMock allows you to mock up SharePoint objects.  Whereas this example shows how to unit test by faking SharePoint objects.
  • As you can see the code fakes the SPSite Object, then we fake the "Contracts" SPList object (fakeContractList). 
  • At this point all properties inside the objects are null.  So our list would simple return a list with no objects.
  • The next step is to create 3 fake list items that are added to the "fakeContractList".
The code below shows the business logic/code of my "Magic 8 Ball":
The method QuestionSPList() has child methods that use SharePoint objects.  This example directly fakes the SharePoint object model to allow for unit testing.
Summary:  I prefer to build my calls to the SharePoint API or any external API's in a low level private service method.  Then all I need to do it stub out the entire method as shown in the 1st example.  Faking the SharePoint object model using TypeMock is a good option for testing SharePoint reliant code. 

More Info:
Paul Hunt has done 3 great blogs on Andrew Woodward's SPRetreat so this will give you another viewpoint on unit testing for SharePoint 2010.

Andrew Woodward has a codeplex project (SharePoint Magic 8 Ball) that will give you tons of example code on unit testing.


Anonymous said...


I can't access the sharepoint site on NUnit.

The error was,

The Web application at [URL] could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.

Any Idea?

Muthuraman M

Post a Comment