Episerver 7 : Unit Testing Using Mocks - Unit Testing Part 2

This is the second part of my unit testing series.  In Unit Testing Part 1 I discussed simple ways that you can organise your project so all the Episerver API dependencies are hidden away in a single file to help improve your sites testability. As of yet we haven't gone into the details of why this helps us so much. In this article we'll start to write some of the unit tests and, hopefully, it should be clear how using Mocks to swap out all of Episerver's dependencies allows us to create testable code.  Before we start I'll be using three packages available from Nuget:

I won't go into the in's and out's of the frameworks, instead I'll mainly be showing some code examples of how to write Mock's for Episerver

Injected - Testing A Controller Using Epi Dependencies

If you look in the Alloy site in the controllers folder, you will soon come across the Injected property.  Interfaces wrapped in an Injected are constructed via new the new service locator using the global service locator object.  This is really cool and useful, however, if you try and do the following test you will get an ActivationException

    public class Controller<T> : PageController<pageType>
    {
        internal Injected<IEpiserverDependencies> EpiserverDependenciesService;

        protected IEpiserverDependencies EpiserverDependencies
        {
            get { return EpiserverDependenciesService.Service; }
        }

         var contentPageController = new Controller();
   }

So, how do we test a view model if it uses Injected for the EpiDependencies ?  This is where we use Mock to mimic the bit that injects the IEpiDependencies into our controller and gets rid of that exception.
            var serviceLocator = new Mock<IServiceLocator>();

            var contentRepositoryFactory = new Mock<IContentRepositoryFactory>();
            var linkResolverFactory = new Mock<ILinkResolverFactory>();

            var epiServerDependencies = new EpiserverDependencies(
                contentRepositoryFactory.Object,
                linkResolverFactory.Object);

            serviceLocator.Setup(x => x.GetInstance<IEpiserverDependencies>()).Returns(epiServerDependencies);

            ServiceLocator.SetLocator(serviceLocator.Object);
If you now create a new Controller, Mock will inject mimic interfaces and classes so our code will load!  This is a big step forward as now you can write unit tests to test the functionality you want.  Below shows a fully working test
        [TestFixtureSetUp]
        public void Setup()
        {
            var serviceLocator = new Mock<IServiceLocator>();

            var contentRepositoryFactory = new Mock<IContentRepositoryFactory>();
            var linkResolverFactory = new Mock<ILinkResolverFactory>();

            var epiServerDependencies = new EpiserverDependencies(
                contentRepositoryFactory.Object,
                linkResolverFactory.Object);

            serviceLocator.Setup(x => x.GetInstance<IEpiserverDependencies>()).Returns(epiServerDependencies);

            ServiceLocator.SetLocator(serviceLocator.Object);
        }

        [Test]
        public void Will_Controller_Load_With_Dependencies()
        {
            var mockContentPage = new Mock<ContentPage>();

            var contentPageController = new ContentPageController();
            var result = contentPageController.Index(mockContentPage.Object);

            result.Should().NotBeNull();
        }

Testing Pages and Content Areas

So, now we have covered how to Mock up a controller, the next bit we can move onto is how to Mock a page up.. specifically a page with a Content Area and items within that area.  This one involves a bit more code, I'm still using the [TestFixtureSetUp] method above. In this test we need to create a content area object, populate it with a content area item object.
        [Test]
        public void Adding_To_Content_Area()
        {
            var content = new Mock<IContent>();
            content.Setup(x => x.ContentLink).Returns(new ContentReference(1));

            var contentAreaItemList = new List<ContentAreaItem>
            {
                new ContentAreaItem { ContentLink = content.Object.ContentLink }
            };

            var contentArea = new Mock<ContentArea>();
            contentArea.Setup(x => x.Items).Returns(contentAreaItemList);

            var mockContentPage = new Mock<ContentPage>();
            mockContentPage.Setup(u => u.MainContentArea).Returns(contentArea.Object);

            var controller = new ContentPageController();
            var contentAreaResult = controller.ReturnContentArea(mockContentPage.Object);

            contentAreaResult.ContentLink.Should().Be(new ContentReference(1));
        }
We now have a test to ensue that the iContent has been added.  This test in itself is pretty boring but it does give you the framework to start fully testing any part of your page types and content areas you might need. The code for the whole of this series can be found on my github.. here enjoy :)

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top