Quantcast
Channel: Tech Blog
Viewing all articles
Browse latest Browse all 49

Unit testing for SharePoint 2010 development

$
0
0

When developing for SharePoint 2010 Unit testing is often overlooked and it shouldn’t be.  It’s true that SharePoint is a product and we don’t need to test that, but the code we write to extend is the same as all other code and needs testing.

Being able to test it though does require a little thought (and potentially a change) to way to you structure your code.  Getting away from running operations against SharePoint inside “CreateChildControls” for example.  You could unit test this method, but personally I think of a web part like a view (or an asp.net code behind file), it’s for presentation logic, not manipulating data or running CAML queries.

The purists amongst you will probably say that this is Integration tests and not Unit tests, and I guess you are correct, I should probably interface out the SharePoint OM etc etc … you are right, but for SharePoint dev, I think this is the best way forward taking time and effort into account – “Is the juice worth the squeeze?” – for me….NO!

I know we don’t need to test the SharePoint OM, but we do need to test our CAML queries – that needs to be ran against a SharePoint implementation, and probably one provisioned with the required lists etc.

Unfortunately getting going with Unit testing in Visual Studio 2010 for SharePoint is not as easy as it should be.  The problems are: SharePoint 2010 is .net 3.5 and 64bit. 

  • MSTest in Visual Studio cannot run tests in 64bit mode.
  • Visual Studio unit test framework is .net 4 only.
  • My favourite (and I think the best free) testing framework MBUnit doesn’t seem to play well with 64 bit in .net 3.5.  The behaviour I see is changing the project type to .net 3.5 simply prompts VS to upgrade the project.  I’ve not looked into this a great deal, but would certainly rather it worked!

 

The solution that seems to be most popular is NUnit.  I only use NUnit for this, that’s a choice thing – its just looks dated to me!  I like Icarus test runner for MBUnit– a lot!

NUnit doesn’t have great integration with Visual Studio, the few bits I found in the Extension gallery were again, .net 4 only.

I recommend you download TestDriven.net– I’ve blogged about this before – I’m a fan!  It makes is super easy to debug and run tests in VS.  Add an External Tool link in VS specifically for NUnit – more on that in a bit.

Creating your tests

Once you’ve installed NUnit from here, and TestDriven.net you’re ready to go..

In Visual Studio, create a class library project and add a reference to NUnit.framework (and probably Microsoft.SharePoint).

Make sure the project is targeting the .net 3.5 framework and the platform target is x64.

Consider you have this simple little helper method just to get you the URL of an item

public class Class1 : IDisposable
{
    SPWeb _web;

    /// <summary>
    /// Inject SPWeb
    /// </summary>
    public Class1(SPWeb web)
    {
        _web = web;
    }

    /// <summary>
    /// Simple example of running a CAML query
    /// </summary>
    public int GetItemIDByTitle(string itemTitle)
    {
        if (String.IsNullOrEmpty(itemTitle))
            throw new ArgumentNullException("itemTitle", "cannot be null or empty");

        try
        {
            SPList configList = _web.Lists["Some List"];
            SPQuery query = new SPQuery();
            query.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + itemTitle + "</Value></Eq></Where>";

            //Should only be 1!
            SPListItemCollection items = configList.GetItems(query);
            if (items.Count > 0)
            {
                return items[0].ID;
            }
        }
        catch (Exception)
        {
            throw;
        }
        return 0;
    }

    /// <summary>
    /// Cleanup
    /// </summary>
    public void Dispose()
    {
        if (_web != null)
        {
            _web.Dispose();
        }
    }
}

 

You can see I am injecting an SPWeb into the class through the constructor.  The method is running a little bit of CAML.

Not the most useful of code snippet I agree!!

Write this little test…

public class DummyTests
{
    Class1 _provider;
    SPSite _site;

    [TestFixtureSetUp]
    public void Setup()
    {
        _site = new SPSite("http://sp2010");
        _provider = new Class1(_site.RootWeb);
    }

    [TestFixtureTearDown]
    public void TearDown()
    {
        _site.Dispose();
        _provider.Dispose();
    }

    [Test]
    public void Get_Item_URL_By_Title_Test()
    {
        string itemTitle = "Some Title";
        int expectedId = 1;

        var item = _provider.GetItemIDByTitle(itemTitle);

        Assert.AreEqual(expectedId, item);
    }
}

 

As mentioned before you have a couple of options for running the tests (there are more, you could buy ReFactor which has some nice stuff – but I haven’t got and can’t afford that!)  I recommend you do both, TestDriven is great for quickly running and debugging a test and the NUnit test runner is great to see all the green ticks when running all your tests!  Even if it is an old, ugly interface with more “80’s grey” than anyone should have to deal with!

Once you have TestDriven.net installed, you can simple right click on the test to debug it…

image

For NUnit, create add a new External Tool entry in VS.  Tools –> External Tools…

image

In the command – be sure to target the 64bit version, actually its just nuit.exe, so I should say be sure NOT to target the x86 version!!

In the arguments text box, use the helper to get the placeholders for BinDir and TargetName, adding the “/run” argument will run the tests automatically when the nuit runner opens.

You’ll then get a new entry on the Tools menu – hit that and your tests should run….

image

Lovely!

More / Resources:


Viewing all articles
Browse latest Browse all 49

Trending Articles