How To Use Moq To Unit Test Episerver

Mocking the Content Repository

One of the most useful unit testing tools available to you as a developer is Moq.  Moq is a lightweight mocking framework that will allow you to get a lot more test coverage in your projects.  If you have never used a mocking framework it might be a little daunting at first but Moq is very easy to use.

Adding Moq To A Project

You can add Moq to your project, via Nuget. On your test project in visual studio, right click on the project:

setting_up_moq

In Nuget, type Moq and add it, job done.

setting_up_moq_nuget

Mocking Episerver

With the release of Episerver 7 and MVC, our lives are a lot more easier to unit test our code base.  In the dark and gloomy days of version 6, you had things like the Data factory that made life a lot more difficult to test properly.

If you’re reading this and you still don’t really get it, then I’ll try to give an example before we dig into the code.  Say you use a page type to hold some metadata like a list of countries that you ship your products to.

You want to unit test your shopping basket, however, within the code some logic exists that calls the episerver api to check that the country has a matching entry in episerver for validation purposes. Cool?

You write your unit test and it throws an object reference exception when you make a call to the api to get the page.  Why?  When an Episerver loads a number of configurations and process related values are set-up, this allows the api to work, iis to work and a whole host of other goodies.

When you run your unit tests, these won’t have access to them.  So in your unit test you may have some code that works on your live site but throws an exception when you test it.  To get over this dilemma, we can use mocks to fake the request to the episerver database and return an object of our choosing.. enter mock.  It creates a pretend object that your code thinks is a real object but allows you as a developer a lot more freedom.

Mocking Pages

One of the most frequent things you need to Mock are pages. Mocking a page is very easy, you create a page within Mock (in the same way you create a List<>). First, you use the Mock<> keyword and place the thing you want to mock as the type.  To use the mocked object you need to call .Object() to get the correct type returned.

var myPageType = new Mock<PageType>();
myPageType.SetUp(x => x.PageName).Returns("Page Name");

The code to mock a page is simple.  Wrap the IContentRepository into mock and then use it via the .Object() method.

Mocking the Content Repository

Up next is mocking the Episerver API.  The most used API is the ContentRepository.  This lets you do stuff with pages and blocks, like load, find and search.

var contentRepository = new Mock<IContentRepository>();
contentRepository .Object();

Mocking Content Repository is also very easy;  we pass the type of IContentRepository into the mock and then use it via the .Object() method.

Mocking Get<> Within the Content Repository

Now we have mocked the content repository, I’m guessing you will want to do some stuff with it.  If you try and get a page from the mocked content repository, it will return null.  As in the example mentioned above, you may have code that relies on a pages to be returned. When you run the code in a live environment, your code always returns a value, so we also need a way to repeat the same thing in your test environment.

var myPageType = new Mock<PageType>();
contentRepository.Setup(x => x.Get<PageType>(It.IsAny<ContentReference>()))
.Returns(myPageType .Object);

To Moq a Get<> call, we first need to mock the page we want to return.  In this example I’m using the It.IsAny() as the input parameter in my Setup method.  This bit of code is tell Moq that a match exists when any content reference is passed in.  We then use a Returns() qualifier that tells Moq what to return when it finds a match.  In this example it will be our mocked page type.

In case you’re wondering how this will work in your unit test class, you would put the code above somewhere like your SetUp method and then in your unit test you would use this code to return your mocked page:

var contentReference = new ContentReference();
contentRepository.Get<PageType>(contentReference);

Mocking GetChildren<> Within Content Repository

So, now we have covered how to get a single page back from Episerver, let’s move onto multiple pages:

var myPageType = new Mock<PageType>();
contentRepository.Setup(x => x.GetChildren<PageType>(It.IsAny<ContentReference>()))
.Returns(new[] { myPageType .Object });

In our code, we tell Moq that a valid match occurs when GetChildren is called with any Content Reference.  In your unit tests you could write code similar to this and you would get an enumerable list with myPageType returned in it.

var contentReference = new ContentReference();
var list = contentRepository.GetChildren<PageType>(contentReference);

Returning Nulls

As we have just talked about GetChildren<> there may be situations when you want to return null.  In your return, if you try to return null, your Moq will throw an exception as it won’t know what constructor to use, instead of just returning null you need to return a type then null:

contentRepository.Setup(x => x.GetChildren<ConfigurationPage>(It.IsAny<ContentReference>()))
.Returns((IEnumerable<ConfigurationPage>)null);

Checking An Interface Within A Method Has Been Called

Sometimes you may have some logic in your class that calls some dependency or what not.  In some instances the dependancy it’s calling will have it’s own set up unit tests so the main thing you care about is to have a confirmation that the inner class/dependency has been called.  We can do this in Moq using the .Verifiable() and.Verify() methods.

[TestMethod]
public void Test_Feature()
{
var cacheHelper = new Mock<ICacheHelper>();
cacheHelper.Setup(m => m.AddToCache(It.IsAny<string>()))
.Verifiable();
var classToTest = new ClassToTest(cacheHelper.Object);
classToTest.TestMethod();
cacheHelper.Verify(x => x.AddToCache(It.IsAny<string>()));
}

Conclusion

In this article we’ve covered what Moq is and I’ve gone over some common code snippets you’ll need to unit test your projects. Moq is incredibly easy to pick up once you know how.

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

More Posts

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *