EPiServer: Unit test classes with Injected properties

This will be a very short entry but I thought it’d be useful to write it down. When you work with EPiServer you may end up having to use property injection. It is very simple, you add a property of type Injected<T>, where T is the interface of whatever you want injected, and the implementation of your interface (according to your DI-settings) will be injected in to this property.
Even though I’m not a huge fan of this solution it seems to be pretty widely used and if you use it, you want to unit test code that uses it.

To test classes with injected properties you want to create your own ServiceLocator which returns a mock of whatever is being used in the code you want to test. I’ve compiled a small scenario where a class of mine, TestClass, has a property of type Injected<IContentLoader> which a method, StuffDoer, uses. I want to mock the injected property to see if it’s being called, here is the code:

public class TestClass
{
    private Injected<IContentLoader> _contentLoader;

    public void StuffDoer(SiteDefinition definition)
    {
        var stuff = _contentLoader
            .Service
            .Get<PageData>(definition.StartPage);

        //And a whole lot of other stuff...
    }
}

[TestFixture]
public class StuffDoesTests
{
    private Mock<IContentLoader> _mockContentLoader;
    private TestClass _testClass;

    [SetUp]
    public void CreateRequirements()
    {
        //Mock the content loader
        _mockContentLoader = new Mock<IContentLoader>();

        _testClass = new TestClass();
    }
    [Test]
    public void IsGet_Called()
    {
        using (ShimsContext.Create())
        {
            //Mock the service locator
            var serviceLocator = new Mock<IServiceLocator>();
            serviceLocator
                .Setup(x => x.GetInstance<IContentLoader>())
                .Returns(_mockContentLoader.Object);

            //Set your mocked service locator to be used
            ServiceLocator.SetLocator(serviceLocator.Object);

            //Call your method
            _testClass.StuffDoer(new SiteDefinition());

            //Verify that the Get<T> method was called!
            _mockContentLoader
                .Verify(x => x.Get<PageData>(It.IsAny<ContentReference>()), Times.Exactly(1));
        }
    }
}