Episerver 7 : Unit Testing Using Fakes – Unit Testing Part 3

This is the third post in my unit testing series.  So far we have created a single Epi Dependencies class to manage ll or Epi Servers API in a single place.  In the second post, we created some basic unit tests using Moq to mock up these dependencies to make previously un-testable code testable.  In this post, I’m going to talk about Fakes.  If you have never heard about a fake then the concept is very easy…  it’s a class that implements an interface you want to test.

The questions I get asked a lot is why use fakes at all, why not use Mocks, or, when should I use which method?  In general, I would favour Mocks as creating a Fake means you have code to maintain.  The reason for using a Fake, however, is that not everything in Epi-Server is mockable, take this example:

var baseDependencies = new Mock<EpiDependencies>();
baseDependencies.Setup(x => x.ContentRepository.Get<ImageFile>(new ContentReference(ImageContentId))).Returns(mockImage);

If you run this bit of code (from the example code provided at the end of this post) Moq will throw an exception

‘System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: mock => mock.ContentRepository’

This means that because the ContentRepository is not virtual, it cannot be mocked. In this example, as we are using EpiDependencies, which is a class we have created, it’s not such a big deal, however, you can’t do this in every circumstance.  If you try to unit test Episerver Commerce for example you will hit this issue a lot.

In our example, EpiDependencies inherits from IEpiDependencies.  What we can now do is create a FakeEpiDependencies object that inherits from IEpiDependencies and makes the ContentRepository repository virtual, allowing us to Mock the function we want to.

public class FakeDepencies : IEpiDependencies
{
public ILinkResolverFactory LinkResolverFactory
{
get
{
return new FakeLinkResovlerFactory();
}
}
public virtual IContentRepositoryFactory ContentRepositoryFactory
{
get
{
return new FakeContentRepositoryFactory();
}
}
}

We now have our fake object that we can pass into anywhere that expects IEpiDependencies; this method is now virtual meaning if we now tried the code that failed above and replace the object to mock from EpiDependencies to FakeDependencies, our code will now run!

var baseDependencies = new Mock<FakeDependencies >();
baseDependencies.Setup(x => x.ContentRepository.Get<ImageFile>(new ContentReference(ImageContentId))).Returns(mockImage);

This might seem quite trivial but it’s a massive help in getting full test coverage in your application.  In many of Episervers API’s (commerce is a much worse offender) you might want to test a function like adding a billing address to a customer and you can’t change the underlining API code to make it testable.  If it uses an interface, you can create a Fake object, override setters or even write custom code within the Fake to allow you to create more in-depth tests that dig deeper into your application.

At the end of this process my unit test then looked like this:

[TestMethod]
public void Image_Alt_Test_Sets_Correctly()
{
var image = new ImageFile
{
AlternativeText = "Test"
};
var block = new Mock<Block>();
block.Setup(x => x.ImageUrl).Returns(new ContentReference(99));
var fakeBaseDependencies = new Mock<FakeBaseDependencies>();
fakeBaseDependencies.Setup(x => x.ContentRepository.Get<ImageFile>(new ContentReference(99))).Returns(image);
viewModel = new kViewModel(block.Object, fakeBaseDependencies.Object);
viewModel .ImageAlt.Should().Be(AltText);
}

Another good example of using a Fake is to cut down on the amount of code in your test projects.  Take our Dependencies class.  If you need to pass epi dependencies into all your view models, blocks, controllers, fixtures etc.. writing the same code over to mock it up is a waste.  One way to get around this would be to create a base class which set the mocks up for you and an alternative and simpler approach would be to create a FakeDepencies class and then use Mock within the properties that retrieve the dependencies.  Using this approach means you write less code as the set-up code is all stored within one place.

public class FakeDependencies : IEpiDependencies
{
public ILinkResolverFactory LinkResolverFactory
{
get
{
var linkResolverFactory = new Mock<ILinkResolverFactory>();
return linkResolverFactory.Object;
}
}
public virtual IContentRepositoryFactory ContentRepositoryFactory
{
get
{
var contentRepositoryFactory = new Mock<IContentRepositoryFactory>();
return contentRepositoryFactory.Object;
}
}
}

If you end up creating an Epi Commerce dependencies handler, which has a lot of API’s and dependencies, that file will end up being quite large and this trick will save you time having to mock the whole thing up each time 🙂

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

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 *