In this tutorial, you will learn how to use write testable Episerver code. This is the second part of my unit testing series. In Unit Testing Part 1 I outlined an approach that you can follow so all of your project's dependencies are included within a single file. Being able to inject a single dependency into your controllers will reduce the burden of updating code whenever a parameter is changed. As of yet, we haven't gone into the details of why this approach simplifies unit testing.
In this article, we'll start to write some of the unit tests making use of this single dependency. We will set up and use mocks to swap out all of Episerver's dependencies in our tests. Before we start I'll be using three packages available from Nuget:
Nunit - a popular unit testing library
Fluent Assertions - a BDD style syntax for writing unit tests
Moq a free .NET mocking framework
Injected - Testing A Controller Using Epi Dependencies
Online you will see a lot of examples that use service locators to inject dependencies within Episerver. This is not good practice and is considered an anti-pattern. To prove this, if you look in the Alloy site within the controller's folder, you will soon come across the Injected
property. Interfaces wrapped in an Injected
are using property injection via service location. One reason why service location is considered bad is due to the hidden nature it creates. From a class how do you know what dependencies it is dependant on? Without looking at the class, if you tried to wrap this code in a test, you would encounter an ActivationException
:
To write unit tests for code that contains dependencies that are injected using Injected<>
you need to use a mocking framework. This is where Moq comes into play. Mock will create a fake object of any type you specify. This will allow the test to run without the code that requires the HTTP context to be set, or a database call to work without data in a database being affected. The code to mock an object is shown below:
The code above mocks this object of type IEpiserverDependencies
and adds it into the service locator. This time when the code is run within your tests and Injected<IEpiserverDependencies>
is called, EpiserverDependenciesService
will be populated with the mock object you created using Moq. Moq will inject this mimic object and the test will run without throwing an exception! This is a big step forward in terms of testability. You can write unit tests to test the functionality you want and not be limited to connections, contexts or anything else that might make the code blow up! Below shows a fully working test for the controller:
Testing Pages and Content Areas
You have the code to mock a controller with a dependency, the next step is to mock an Episerver page object... specifically a page with a Content Area and items within that area. This one involves a bit more set-up code. This setup will be done in the test classes [TestFixtureSetUp]
method. In this test, we need to create a content area object and populate it with fake blocks:
You can now write some code to test that the IContent
items have been added to the content area. This test on its own is pretty boring, however, 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. Happy Coding 🤘