Testing your sharepoint repositories

In this article we will see how to test your sharepoint repositories, as we said before writing unit test for them isn’t easy. I don’t think you can test drive them or that it would help, at the very least it would be too slow.

Therefore SHP repositories are a weak point in your testing strategy, but at the very same time they are the base on which the rest of your application sits on. So it is very important that you do two things:

  1. Write KISS repositories
  2. Write integration tests for them

KISS: Keep It Simple Stupid

Your repositories need to be simple, strip them of any logic that has a reason to be somewhere else. Any constraint that isn’t strictly related to the persistent layer should be checked by another layer.

They should receive an entity from above and persist it like it is, if the entity comes with errors those errors will be persisted (or the layer bellow will throw an exception).

Expose a basic API. Instead of a method Save that check if the entities exists and then decides whether to update it or create a new entity expose three basic methods (Exists, Create, Update) and let the layer above make that decision.

Once you have a KISS repository you need to secure it the best you can. This is done by writing tests integrated with sharepoint. Usually to do this you will have to do the following things:

  1. Create a test site collection
  2. Provision your artifacts (Fields, ContentTypes, Lists…)
  3. For each test
    1. Populate one or more list
    2. Run a test
    3. Clean up
  4. Delete the site collection

This is obviously a very slow process so you won’t run this tests in your normal TDD cycle, but you can run them frequently enough that you will catch most bugs before they can cause any major problem.

Now let’s put aside the theory and write some code, starting from the repository of the previous article

    private const string WebAppUrl = "http://localhost";
    private const string SiteUrl = "http://localhost/sites/Test";
    private IPersonRepository repository;
    private SPSite site;

    [SetUp]
    public void SetUp()
    {
      site = CreateSite();
      repository = new PersonRepository(site.RootWeb);
    }

    [Test]
    public void WhenAddingAPerson__ItShouldAddAPerson()
    {
      var list = site.RootWeb.Lists["Person"];
      CleanList(list);

      var person = AddPerson();

      AssertCreation(list, person);
    }

    private SPSite CreateSite()
    {
      var webapp = SPWebApplication.Lookup(new Uri(WebAppUrl));

      if (SPSite.Exists(new Uri(SiteUrl)))
        webapp.Sites.Delete(SiteUrl);

      var site = webapp.Sites.Add(SiteUrl, "contoso\\admin", "admin@contoso.com");
      site.Features.Add(new Guid("<GUID>"));
      return site;
    }

    private void CleanList(SPList list)
    {
      while (list.Items.Count > 0)
        list.Items[0].Delete();
    }

    private Person AddPerson()
    {
      var person = new Person
      {
        Address = "Address",
        BirthDate = DateTime.Now,
        Name = "Name"
      };
      repository.Create(person);
      return person;
    }

    private void AssertCreation(SPList list, Person person)
    {
      Assert.That(list.Items.Count, Is.EqualsTo(1));
      var item = list.Items[0];
      Assert.That(item["Address"], Is.EqualsTo(person.Address));
      Assert.That(item["Title"], Is.EqualsTo(person.Name));
      Assert.That(item["DateOfBirth"], Is.EqualsTo(person.BirthDate));
    }

Here we see a setup method that creates (or recreates) a site collection at every test run. To speed up the tests a bit, you can move that operation to a Fixture Setup, but that might mean that some tests pass or fail depending on the order of execution, so proceed with care. During the site creation we also enable one (or more) features that provision our sharepoint artifacts.

We then have the test method that checks that the Create method of the repository works fine by:

  1. Removing any item present on the list
  2. Calling the Create method with a valid person
  3. Checking (via standard object model) that was added an item to the expected list with the required properties.

In the same way one might test a Get method. First you clean the list, than you add the expected item (via SSOM), than you get it with your repository and assert that everything is fine. Try it doing it yourself and let me know if you have any problem.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s