Archive

Archive for April, 2017

Easy unit testing in Sitecore with AutoFixture, NSubstitute and Xunit

03/04/2017 Leave a comment

Unit testing Sitecore code has been around for quite som years now, and with the release of version 8.2 Sitecore has implemented a lot of new abstractions, which makes testing of Sitecore code easier. So if you not on 8.2 yet this might not be for you, or this could be a reason for upgrading to 8.2. Today there exists a couple of framework that will help developers with writing unit test to Sitecore one of the more known ones I Sitecore FakeDb. But as we shall see in the following a good portion of the more simple Sitecore API can easyli be test without, but creating test stubs can quick become a cumbersome tasks, and this is exactly where this post comes into play.

Let me briefly introduce AutoFixture

This is take from The AutoFixture Github pages https://github.com/AutoFixture/AutoFixture

AutoFixture is an open source library for .NET designed to minimize the ‘Arrange’ phase of your unit tests in order to maximize maintainability. Its primary goal is to allow developers to focus on what is being tested rather than how to setup the test scenario, by making it easier to create object graphs containing test data.

For me Autofixture helps me writing clean Tests where magic values, or test object are hidden away, ie dummy data is something created when the test runs. I strongly encourage you to take a deeper look at Autofixture it is an awesome Library

Okay so how does this combined with Xuint and NSubstitute. Today You can create an Subsitute for a Sitecore Item But it stille take quite som parameters to create the item so you need to create more than one Substitute see the example below.


  var db = Substitute.For<Database>();
  var itemId = ID.NewID;
  var language = Substitute.For<Language>();
  var definition = new ItemDefinition(
  itemId, "itemname", ID.NewID, ID.NewID);
  var data = new ItemData(
    definition, language,
    Sitecore.Data.Version.First, new FieldList());
  var item = Substitute.For<Item>(itemId, data, db);
  return item;

You could in your test have a test factory that just creates this object for you of course.

Enough Skip to the point .. okay lets see where you getting at.

Okay given the following class Which I want to test. All it does is, for the master database get the root item and add a ChildItem, with any TemplateId and return the newly created child.

public class MyClass
{
   private readonly IFactory _factory;
     public MyClass(IFactory factory)
     {
        _factory = factory;
     }

     public Item AddToSitecore()
     {
      Database database = _factory.GetDatabase("master");
      Item rootItem = database.GetItem("/sitecore/content/home");
      Item childItem = rootItem.Add("child", new TemplateID(ID.NewID));
      return childItem;
    }
}

I can write the following test

  using FluentAssertions;
  using NSubstitute;
  using Sitecore.Abstractions;
  using Sitecore.Data;
  using Sitecore.Data.Items;
  using Xunit;


namespace Sitecore.AutoFixture.NSubstitute
{
  public class MyClassTests
  {

   [Theory, AutoSitecoreData]
   public void MyClass_AddItemToWithAutoFixtureRoot_ShouldReturnItem(Item rootItem,Item childItem,Database database,IFactory factory)
   {
     //Arrange
     database.GetItem("/sitecore/content/home").Returns(rootItem);
     factory.GetDatabase("master").Returns(database);
     rootItem.Add(Arg.Any<string>(), Arg.Any<TemplateID>()).ReturnsForAnyArgs(childItem);
     MyClass sut = new MyClass(factory);

    //Act
    Item returnItem = sut.AddToSitecore();

   //Assert
   returnItem.Should().NotBeNull();
   returnItem.ID.Should().BeSameAs(childItem.ID);
   returnItem.Name.Should().BeEquivalentTo(childItem.Name);
   rootItem.Add(Arg.Any<string>(), Arg.Any<TemplateID>()).Received();
   database.GetItem("/sitecore/content/home").Received();

  }
 }
}

What is nice here is you can the easy created Database and Items (root,and child), and a Sitecore Factory, you can set your expectations in your own test to match what you’re testing.

All with the help of the  AutoSitecoreData Attribute that decorates the tests.

It magically creates new items, database, Sitecore factories, Settings, the last two fund in Sitecore Abstractions. No need for Factories, all you get is relevant data with out static items or

It’s not entirely magic, it extends some AutoFixture attributes, you can have a look at the code at Github

https://github.com/istern/Sitecore.AutoFixture.NSubstitute

 

There Are a few gotchas For this to work in your test, you need to get the code from Github  and build it, Hopefully I will soon build a nuget package which will make this step obsolete . But once build you can reference the SitecoreAutoDataAttribute in your tests. You will also have to reference Sitecore.Kernel but no additional references to Sitecore files is required.

Hope you will find this useful

Categories: Sitecore 8, Unit Testing Tags: ,